Scanf und Leerzeichen



  • Es geht jetzt nicht darum etwas anderes als scanf zu zu nutzen..

    ICh werde noch wahnsinnig mit C
    Schreibe ich folgendes, kann ich
    Vorname:Timo Peter
    Nachname: Meyer
    eingeben und es geht

    #include <stdio.h>
    #define cls system("cls");
    char a [1][1][25];
    int main(){
        system("color 1E");
        cls
        printf("Vorname:");
         scanf("%[a-z, ,A-Z]s",a[0][0]);
        printf("Nachname:");
         scanf("%s",a[0][1]);
        printf("Willkommen, %s %s",a[0][0], a[0][1]);
    }
    

    Schreibe ich aber, um z.B:
    Vorname:Timo Ulrich
    Nachname:Meyer Schmidt
    eingeben zu können folgendes, kann ich nur die Vornamen eingeben und er
    springt dann sofort auf Wilkommen xyz
    WIESO?!

    #include <stdio.h>
    #define cls system("cls");
    char a [1][1][25];
    int main(){
        system("color 1E");
        cls
        printf("Vorname:");
         scanf("%[a-z, ,A-Z]s",a[0][0]);
        printf("Nachname:");
         scanf("%[a-z, ,A-Z]s",a[0][1]);
        printf("Willkommen, %s %s",a[0][0], a[0][1]);
    }
    


  • @corado sagte in Scanf und Leerzeichen:

    Es geht jetzt nicht darum etwas anderes als scanf zu zu nutzen..

    Gerade beim Einlesen von Strings wäre aber die sichere Alternative scanf_s besser!

    char a [1][1][25];

    Was soll a sein?! Ein 3d-Array mit 1x1x25? Warum nicht gleich char a[25]? Besser wäre aber, wenn du 2 Variablen hättest und die sinnvoll benennen würdest:

    char first_name[25];
    char last_name[25];
    

    Anstatt hier irgendwas mit a[0][1] zu veranstalten, wo das Array doch gar nicht so viele Elemente hat.

    Dann (WICHTIG!) benutze scanf NIE NIE OHNE Längenangabe.
    int n_read = scanf(" %24[^\n]", name);
    Dann auch die Rückgabe testen.

    Benutze lieber scanf_s - da kannst du die Länge als Parameter angeben.

    Space - Leerzeichen/Newline am Anfsng skippen. Dann bis 24 Zeichen (außer \n) lesen.

    Ansonsten wäre auch fgets eine Option.



  • Es handelt sich hierbei lediglich um ein Beispielcode um das Problem aufzuzeigen...

    auch mit char a[2][2][25], funktionierte es nicht.
    In meinen Büchern wird mit scanf gearbeitet, mir geht es nur ums Verständnis, mir ist bewusst das man damit nicht mehr arbeitet...auch die Längenbegrenzung etc..



  • Dein "Problem" hat nicht wirklich etwas mit C zu tun sondern mit Deinem Verständnis von Filestreams. Wenn Du "Foo Bar" eingibst, dann liest Dein scanf("%s", whatever); bis zum ersten Leerzeichen Whitespace. Der Rest bleibt im input stream und wird von Deinem nächsten scanf("%s", whatever); gelesen. Du brauchst also eine andere Methode um zusammengesetzte Namen zu lesen die Whitespace enthalten können.

    Je nach Platform hilft Dir vielleicht getline(). Sonst brauchst Du vielleicht etwas zeichenbasiertes mit dem Du Dir selbst etwas bastelst, zB getc().



  • @corado Der Formatspecifier für das Set ist nur [ und nicht s mit vorangestelltem [].
    Wenn Zeichen nicht zu einem Formatspecifiere gehören, müssen sie im Eingabestrom vorhanden sein. (Whitespace stehen für beliebig viele und jede Art von Whitespace)

    Und %[ ist auch kein regulärer Ausdruck, sondern eine sture Angabe der Zeichen. Besondere Zeichen sind lediglich ^ und -. Das Komma kann bei dir Bestandteil des Namens sein und ist eher weniger sinnvoll. Ein - dagegen kann bei Doppelnamen vorkommen.

    Nach dem Vornahmen steht noch das \n im Eingabestrom. Das kann man mit einem Whitespace im Formatstring überlesen (außer %c und %[ machen das sonst alle Formatspecifier automatisch)

    Ein führendes Leerzeichen vor dem %[ (hier direkt hinter dem ") kann helfen.
    scanf(" %[ a-zA-Z-]",a[0][1]);



  • @DirkB Diese Scansets bei scanf() verdräng' ich immer wieder weil man damit auch jeden erdenklichen Mist lesen kann und dann im nachhinein nochmal die Eingabe validieren und bereinigen muss. Ich bin eher der Typ "early discard/exit" wenn etwas nicht den Erwartungen entspricht (und den rest ohne Verarbeitung wegwerfen).



  • @DirkB
    Super:-) Danke, werde mir das nachher noch mal genauer ansehen um nachvollziehen zu können was da genau passiert



  • @Swordfish sagte in Scanf und Leerzeichen:

    @DirkB Diese Scansets bei scanf() verdräng' ich immer wieder weil man damit auch jeden erdenklichen Mist lesen kann und dann im nachhinein nochmal die Eingabe validieren und bereinigen muss. Ich bin eher der Typ "early discard/exit" wenn etwas nicht den Erwartungen entspricht (und den rest ohne Verarbeitung wegwerfen).

    Es kommt auch immer etwas darauf an, ob man Eingaben von Maschinen lesen möchte (oft klar definiert) oder vom Menschen, der irgendwelchen Müll eingibt.



  • Hallo corado!

    Warum machst du nicht so was:

    scanf("%[^\n]", c_name);

    #include <stdio.h>
    #include <stdlib.h>
    
    void clpuf(void)
     {
     while (getc(stdin) != '\n')
        ;
     }
    
    int main()
    {
     int i;
     char c_posi[200],  c_nega[200];
    
     for (i = 0; i < 200; i++)
          c_posi[i] = c_nega[i] = 0;
    
     printf("Beispiel Positiv- und negativ Liste bei scanf\n");
    
     printf("\nBitte zum Test einen String\nMuster.....: 123430abc  \neingeben.\nEingabe:  ");
    
    /** liest nur Zeichen ein die innerhalb der eckigen Klammern stehen
       * und beendet die Eingabe in  die Variable beim ersten Zeichen, das nicht
       * in der Liste steht*/
     scanf("%[0123456789+-*/=]", c_posi);
     printf("Die Eingabe war: %s \n\n", c_posi);
    
     /** Beseitigt die restlichen im Tastaturpuffer stehenden Zeichen, da diese sonst
       * bei der naechsten Eingabe wieder verwendet werden */
     clpuf();
    
     printf("\nBitte zum Test einen String\nMuster.....: asdfgh123  \neingeben.\nEingabe:  ");
     scanf("%[^1234567890]", c_nega);
     printf("Die Eingabe war: %s \n\n", c_nega);
    
     clpuf(); /** Tastaturpuffer leeren*/
    
     printf("\nBitte zum Test einen String mit Leerzeichen eingeben\nEingabe:  ");
     /** liest alle Zeichen außer den Newline-Zeichen(Enter-Taste) ein*/
     scanf("%19[^\n]", c_nega);
     printf("Die Eingabe war: %s \n\n", c_nega);
    
     printf("Das Programm wird nun beendet.....\n");
    return EXIT_SUCCESS;
    }`
    
    Mit19 kannst du in diesen Beispiel die Zahl der einzulesenden Zeichen begrenzen, um das abzusichern. 
    Sorry aber ich hatte dieses Jahr im Januar einen sehr schweren Arbeitsunfall. Ich hoffe i am back again.
    Laut dem Docs bin ich frühestens wieder Ende 2099 wieder arbeitsfähig. Dann bin ich 134 Jahre alt.
    Viel Spaß beim ausprobieren.
    
    Rustyoldguy

Anmelden zum Antworten