Funktion für nur Zahlen und nur Buchstaben



  • volkard schrieb:

    du darfst inzwischen sogar in C kleine funktionen bauen. SCNR

    und du hast dich dumm gestellt und im nöchsten hab ich dich wie nen nube behandelt und dann hast du mir unterstellt, ich würde kein c können und es wurde komisch.

    Ich wusste einfach nicht, was Du meinst. Ich dachte, Du meinst, dass ich Code geschrieben habe, der ueber den Bereich der aktuellen Uebungsaufgaben des OP hinausgeht.

    volkard schrieb:

    kürzer wäre egal. leichter zu lesen. was du nicht weißt oder nicht zugibst, ist, daß leicht lesbarer code anzustreben ist.

    Das ist er sowieso immer. Ich hab halt so viel Erfahrung, dass ich den Code, den ich gepostet habe fuer supereinfach und superleicht zu lesen gehalten habe, deswegen habe ich auch zuerst fast keine Kommentare reingeschrieben, weil der Code so kurz war.

    Die readnum() Funktion ist ein Mini-Parser, der Zahlen aus einer Zeile des Eingabestroms filtert.
    Ich habe es nur deswegen in eine Funktion gepackt, damit es moeglichst kompakt ist und nicht in X Funktionen aufgesplittet ist.

    So einen Programmierstil kann man auch als besonders lesbar betrachten.

    volkard schrieb:

    hast dich so gegeben, indem du eisern behauptetest, daß der code so ok sei.

    Das ist er auch -- fuer mich, und etliche andere, die mit viel schlimmeren Dingen zu tun haben.

    Das mit der Vorbildfunktion sehe ich natuerlich ein, aber wenn ich jedesmal 10 mal wuerfeln muss, wenn ich jemanden helfen will, kann ich's auch gleich ganz lassen.

    volkard schrieb:

    auch während dieses threads hab ich durchaus in anderen threads hilfreiche tips gegeben. und das hier war auch notwendig. ist halt besser, wenn unser programmierernachwuchs gleich erfährt, daß "hauptsache, der compiler frißt es" nucht mehr ein brauchbares motto ist.

    Es gibt in der Praxis aber so gut wie gar keinen Code, der irgendeiner Regel gerecht wird. Jeder programmiert am Ende doch nur so, wie er es will.

    Frueher dachte ich auch mal so, wie Du, dass es ein hehres Ziel sei, besonders guten und sauberen Code zu schreiben, und dass man das am besten jedem unter die Nase reibt.

    Mittlerweile stehe ich auf dem Standpunkt, dass es egal ist, wie jemand programmiert, Hauptsache der Code laeuft. Wenn man will, kann man jeden Code verstehen, auch wenn er nicht im eigenen Stil geschrieben ist.

    Das wird vor allem dann wichtig, wenn man fuer eine Firma arbeitet und den Code von anderen Leuten warten muss. Wenn man dann den Code nicht versteht, kann man sich gleich einsargen lassn (natuerlich kommt mit der Zeit auch Erfahrung dazu).

    Aber ich geb Dir Recht, dass es gut ist, Anfaengern gleich von Anfang an guten Code beizubringen.

    Was guter Code ist, ist aber von Betrachter zu Betrachter unterschiedlich, wie man hier deutlich sehen kann.

    volkard schrieb:

    lies einfach ein wenig mit und weise mir schlechten code nach und schau, wie ich reagiere. wahrscheinlich sage ich "ups, hast recht" oder sowas. ich sage aber vermutlich nicht "du magst meinen code nicht? ich geb dir mal nen link auf den standard, wo er erklärt ist".

    OK! 😃

    Da faellt mir auch gleich was ein: In einem anderen Thread hast Du eine Funktion mit

    void func() {
    }
    

    deklariert. Seit C90 sollte das aber

    void func( void ) {
    }
    

    heissen. 😉



  • Power Off schrieb:

    Da faellt mir auch gleich was ein: In einem anderen Thread hast Du eine Funktion mit

    void func() {
    }
    

    deklariert. Seit C90 sollte das aber

    void func( void ) {
    }
    

    heissen. 😉

    jup.
    zum beispiel in http://www.c-plusplus.net/forum/viewtopic-var-t-is-121640-and-highlight-is-.html
    das liegt daran, daß ich c++ gewohnt bin und dort ist () so definiert, daß keine argumente erlaubt sind, also identisch mit (void). in c++ sollte man kein (void) mehr schreiben.
    in c schrieb ich natürlich auch immer (void), wie sich das da gehört. habs einfach vergessen.



  • Power Off schrieb:

    Frueher dachte ich auch mal so, wie Du, dass es ein hehres Ziel sei, besonders guten und sauberen Code zu schreiben, und dass man das am besten jedem unter die Nase reibt.

    es geht für dich erstmal darum, daß du auch nach dem schreiben kurz mal drüber nachdenkst und gegebenenfalls was verbesserst. nicht um diesen konkreten code besser zu haben. das wäre zu einfach. es hat dann den zweck, daß du das nächste mal es gleich richtig machst. es geht darum, eine rückkopplung zu haben, die einen dazu führt, daß man immer besser wird. daß man auf anhieb das feinste sprachmittel sieht. daß man auf anhieb die schnellste implemetierung der schleife sieht. daß man auf anhieb den fehler erkennt. kurz: es geht darum, dich ständig zu verbessern und nicht auf lorbeeren auszuruhen.
    siehe http://www.c-plusplus.net/forum/viewtopic-var-t-is-121246-and-postdays-is-0-and-postorder-is-asc-and-start-is-0.html
    klar kann ich sowas mit nur einer hand schreiben und auch fremden code lesen und den fehler auf anhieb sehen. aber ich bin einfach nicht gut genug, muß immer besser werden. nicht nur im verständnis der verrücktesten metaprogrammierungstricks, auch in den grundlagen. und sag nicht, du hättest keine solchen mikro-lücken.

    Mittlerweile stehe ich auf dem Standpunkt, dass es egal ist, wie jemand programmiert, Hauptsache der Code laeuft.

    komisch. mittlerweile stehe ich niht mehr auf dem standpunkt. wir machen temporal gegenläufige entwicklungen durch.

    Aber ich geb Dir Recht, dass es gut ist, Anfaengern gleich von Anfang an guten Code beizubringen.
    Was guter Code ist, ist aber von Betrachter zu Betrachter unterschiedlich, wie man hier deutlich sehen kann.

    jup. vor 8 jahren hab ich auch manchmal viele funktionen zu einer großen zusammengefaßt, weil die nubes gerne vergessen hatten, was welche funktion macht. naja, das hat aber nix gebracht. die nubes müssen eh lernen, mit vielen funktionen klar zu kommen. und wenn man so leichte sachen wie

    bool isDigit(char ch){
       return '0'<=ch && ch<='9';
    }
    

    reinschmiert, wird auch keiner meckern. wer schon in der lage ist, sich sowas wie isDigit zu merken, hat mehr spaß dran, damit den mini-parser zu lesen. und wer's noch nicht kann, übt das richtige.

    edit: aber da ich auch c++ lehre, muß ich an mich auch andere maßstäbe anlegen, als wenn ich nur c++ benutzen würde. ich muß ja guten gewissens sein, die schüler auf einen weg zu führen, der sie in den folgenden jahren möglichst weit bringt.



  • Hier ist mir schon wieder was in Deinem "Anfaenger-Code" aufgefallen:

    volkard schrieb:

    bool isDigit(char ch){
       return '0'<=ch && ch<='9';
    }
    

    1. Den Datentyp "bool" gibt es erst seit C99. Es gibt immer noch viele Compiler, die keinen bool-Typ haben. Also solltest Du zumindest so etwas wie

    #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
    typedef enum { false, true } bool;  /* fuer alte Compiler */
    #endif
    

    dazuschreiben. Wenn Dein Anfaenger den Code compilieren will und ein Error wegen "bool" kriegt, kann das ganz schoen frusten.
    Deswegen nehme ich in Beispielen immer noch "int" statt "bool". Das muss mir natuerlich niemand nachmachen.

    2. Im Gegensatz zu C++ sind in C Zeichenkonstanten vom Typ "int", und nicht "char".

    Der Anfaenger nimmt bei Deinem Beispiel an, dass '0' und '9' vom Typ 'char' waeren, weil Du das in den Parameter geschrieben hast.
    Dann wundert er sich, wenn Zeichen jenseits der ASCII-Range in switch-Anweisungen nicht mehr funktionieren, die er mittels der C-Standard-Bibliothek eingelesen hat.

    3. Boolescher Ausdruck ohne Kennzeichnung

    Ein Anfaenger koennte Verstaendnisprobleme kriegen, wenn er den Ausdruck "return '0' <= ch && ch <= '9';" liest.
    Daher waere es besser, ueber den Conditional-If-Operator zu zeigen, welche Werte wann zurueckgegeben werden.
    Das liest sich auch viel besser, uebrigens.

    Daher sollte das Codeschnipsel entweder so:

    #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
    typedef enum { false, true } bool;  /* fuer alte Compiler */
    #endif
    bool isDigit( int ch ){
       return '0' <= ch && ch <= '9' ? true : false;
    }
    

    oder so:

    int isDigit( int ch ){
       return '0' <= ch && ch <= '9' ? 1 : 0;
    }
    

    aussehen.



  • mit punkt 3 hast du dich endgültig disqualifiziert



  • jup schrieb:

    mit punkt 3 hast du dich endgültig disqualifiziert

    Ja, ja, die Klugscheisser sind wieder am Werk.
    Ich hoffe, dass Du mal ein besonders fettes Projekt aufs Auge gedrueckt kriegst.
    Nach Volkard's Modell mit 100.000 Funktionen in 1.000.000 Zeilen Source (nach der Regel: nie mehr als 10 Zeilen!).



  • Power Off schrieb:

    Nach Volkard's Modell mit 100.000 Funktionen in 1.000.000 Zeilen Source (nach der Regel: nie mehr als 10 Zeilen!).

    und nie mehr als 10 funktionen pro datei.
    ok, werden zwar 10000 dateien und alte dateisysteme kippen aus den latschen, aber es wird wahnsinnig übersichtlich.



  • volkard schrieb:

    ok, werden zwar 10000 dateien und alte dateisysteme kippen aus den latschen, aber es wird wahnsinnig übersichtlich.

    Ja, na klar, super-uebersichtlich. Mein Freund heisst GREP. Hast Du GREP, bist Du niemals allein. 🙄



  • Ich bin Dein Freund! 🙂



  • bool isDigit( int ch ){
       return '0' <= ch && ch <= '9' ? true : false;
    }
    

    aaaaah...ja wenn der vergleich true ist, gib true zurück. wenn der vergleich false ist, gib false zurück...sehr sinnig. wirklich, das erhöht die übersicht aber gewaltig. 🙄



  • genauso wie

    bool func( void ) {
       return zappidie(137,5) && !zippidie(99,8,2) && ~yippidie(123,4,4,2) && *(zigzag*)yayman(2374,"()!@$%") || alt327(2325,"52323") - 235 >> 35 && b || 7 || c - 345;
    }
    


  • Ich würde das vorschlagen, wenn man es den Anfängern unbedingt klarer machen will.

    int isDigit(int ch)
    {
        if('0' <= ch && ch <= '9')
        {
            return 1;
        }
    
        return 0;
    }
    


  • Stimmt, viel uebersichtlicher! 🙂 👍



  • wie waers mit...?

    int isDigit(int ch)
    {
        if (ch <= '0')
        {
            return 0;
        }
        else
        if (ch >= '9')
        {
            return 0;
        }
        else
        {
            return 1;
        }
    }
    

    😉

    PS: mit [code] will ich ausdruecken, dass dies fuer mich kein akzeptables C mehr ist.



  • bool isDigit(int ch) {
      switch(ch) {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
          return true;
        default:
          return false;
      }
    }
    

    Übersichtlicher gehts wohl kaum!



  • bool isDigit(int ch) {
      return (((ch - '0') ? false : true) || ((ch - '1') ? false : true) || ((ch - '2') ? false : true) || ((ch - '3') ? false : true) || ((ch - '4') ? false : true) || ((ch - '5') ? false : true) || ((ch - '6') ? false : true) || ((ch - '7') ? false : true) || ((ch - '8') ? false : true) || ((ch - '9') ? false : true)) ? true : false;
    }
    

    Schön, so gefällts mir bisher am besten! Oder man nimmt isdigit...



  • nice jungs! 😋



  • Power Off schrieb:

    1. Den Datentyp "bool" gibt es erst seit C99. Es gibt immer noch viele Compiler, die keinen bool-Typ haben. Also solltest Du zumindest so etwas wie

    #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
    typedef enum { false, true } bool;  /* fuer alte Compiler */
    #endif
    

    dazuschreiben.

    seit 99 sind 6 jahre her.

    2. Im Gegensatz zu C++ sind in C Zeichenkonstanten vom Typ "int", und nicht "char".

    das char dient vor allem der kommentierung, was da reingeht. genauso das bool beim ausgang.

    3. Boolescher Ausdruck ohne Kennzeichnung
    Ein Anfaenger koennte Verstaendnisprobleme kriegen, wenn er den Ausdruck "return '0' <= ch && ch <= '9';" liest.
    Daher waere es besser, ueber den Conditional-If-Operator zu zeigen, welche Werte wann zurueckgegeben werden.

    mit dem ?: behebst du nir ein problem, das entstanden ist, weil du ist statt bool lieferst.

    int isDigit( int ch ){ 
       return '0' <= ch && ch <= '9' ? 1 : 0; 
    }
    

    das ist zu undeutlich, wenn ich deinen gedanken weiterverfolge. denn immernoch muß der anfänger "'0' <= ch && ch <= '9'" lesen und verstehen. das ist auch bei meinem stil ein problem und war eine vernachlässigung, um dich nicht vollends zu erschrecken.
    der nube muß erstmal erkennen, daß die teile '0'<=ch und ch<='9' bereits bool zurückgeben.
    also

    int isDigit( int ch ){ 
       return ( '0' <= ch ? 1 : 0 ) && ( ch <= '9' ? 1 : 0 ) ;
    }
    

    und für den gesamtausdrück natürlich auch nocht. woher soll man sonst wissen, was && zurückgibt?

    int isDigit( int ch ){ 
       return ( '0' <= ch ? 1 : 0 ) && ( ch <= '9' ? 1 : 0 ) ? 1 : 0;
    }
    

    wobei ich finde, daß man statt ?1:0 dahinter viel besser !! davor schreibt.

    int isDigit( int ch ){ 
       return !!( !!('0' <= ch) && !!(ch <= '9') );
    }
    

    ich kann deine gedanken nachvollziehen, aber ich verstehe nicht, warum du das eigentlich machst.

    ich hingegen würde

    bool isDigit( char ch ){ 
       return '0' <= ch && ch <= '9'; 
    }
    

    verbessern zu

    #define RANGE(min,x,max) ((min)<=(x))&&((x)<=(max))
    
    bool isDigit( char ch ){ 
       return RANGE('0',x,'9');
    }
    


  • volkard schrieb:

    seit 99 sind 6 jahre her.

    Sag das mal jemand, der auf einem alten Betriebssystem mit alten Entwicklungswerkzeugen arbeiten muss. Der freut sich bestimmt!

    volkard schrieb:

    das char dient vor allem der kommentierung, was da reingeht. genauso das bool beim ausgang.

    Dabei vernachlaessigst Du das Problem, dass z.B. getchar() Integers zurueckliefert. D.h. beim Aufruf muss man nach char casten. Toll! 👎

    volkard schrieb:

    #define RANGE(min,x,max) ((min)<=(x))&&((x)<=(max))
    
    bool isDigit( char ch ){ 
       return RANGE('0',x,'9');
    }
    

    Prinzipiell sehr schoen, aber die Parameterreihenfolge ist sehr bizarr (von dem Fehler in isDigit() mal abgesehen -- es muss "ch" statt "x" heissen).

    Besser und logischer waere:

    #define RANGE(x,min,max) ((min)<=(x))&&((x)<=(max))
    
    bool isDigit( int ch ){ 
       return RANGE( ch, '0', '9' );
    }
    


  • volkard schrieb:

    mit dem ?: behebst du nir ein problem, das entstanden ist, weil du ist statt bool lieferst.

    Ich verstehe ungefaehr, durch die Tippfehler, was Du damit sagen willst.

    Leider ein weiterer Irrtum von Dir: Der Ergebnistyp eines ? : Operatorpaars ist gleich dem Ergebnistyp des eingetretenen Falles.

    Also liefert bei "bool" der Ausdruck "x ? true : false" auf jeden Fall ein Ergebnis vom Typ bool.

    Siehe auch Kapitel 6.5.15 im C Standard (ISO 9899:1999).

    Die Regel "int always wins" gilt schon seit dem ersten C Standard (1990) nicht mehr.


Anmelden zum Antworten