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 Deinscanf("%s", whatever);
bis zum erstenLeerzeichenWhitespace. Der Rest bleibt im input stream und wird von Deinem nächstenscanf("%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