Das Programm wartet nicht auf Benutzereingaben mit scanf (“% c”, & yn);

Dies ist der Basiscode für ein Programm, das ich zum Üben mit Dateien in C schreibe. Ich versuche herauszufinden, ob die Ausgabedatei bereits existiert und wenn es existiert, möchte ich den Benutzer fragen, ob er sie überschreiben möchte oder nicht. Dies ist der Grund, dass ich die outfilename Datei zuerst mit fopen (outfilename, “r”) geöffnet habe; im Gegensatz zu fopen (outfilename, “w”) ;.

Es erkennt den Fall, dass die Datei nicht existiert, aber wenn sie existiert, führt sie printf aus (“Ausgabedatei existiert bereits, überschreiben (y / n):”); statement ignoriert aber vollständig die scanf (“% c”, & yn); Erklärung!

Der printf am Ende des Programms liest “yn = 0”, wenn die Datei nicht existiert und nur “yn =”, wenn es existiert. Kann mir jemand helfen?

#include  #include  #include  #include  int main(void) { FILE *inf; FILE *outf; char filename[21],outfilename[21]; char yn='0'; printf("Please enter an input filename: "); scanf("%s",&filename); printf("Please enter an output filename: "); scanf("%s",&outfilename); /* Open file for reading */ inf=fopen (filename,"r"); outf=fopen(outfilename,"r"); /*check that input file exists*/ if (inf!=NULL) { /*check that the output file doesn't already exist*/ if (outf==NULL){ fclose(outf); /*if it doesn't already exist create file by opening in "write" mode*/ outf=fopen(outfilename,"w"); } else { /*If the file does exist, give the option to overwrite or not*/ printf("Output file already exists, overwrite (y/n):"); scanf("%c",&yn); } } printf("\n yn=%c \n",yn); return 0; } 

 printf("Please enter an output filename: "); scanf("%s",&outfilename); 

Wenn Sie die zweite Zeichenfolge eingeben und die EINGABETASTE drücken, werden eine Zeichenfolge und ein Zeichen in dem Eingabepuffer platziert, sie sind nämlich die eingegebene Zeichenfolge und das Newline-Zeichen. Die Zeichenfolge wird von dem scanf verbraucht aber das Newline verbleibt in der Eingabe Puffer.

Des Weiteren,

 scanf("%c",&yn); 

Ihr nächster scanf zum Lesen des Zeichens liest / verbraucht nur den Zeilenumbruch und wartet daher niemals auf Benutzereingaben.

Die Lösung besteht darin, die zusätzliche Zeilenschaltung zu verwenden, indem Sie Folgendes verwenden:

 scanf(" %c", &yn); ^^^ < ------------Note the space 

Oder mit getchar()

Vielleicht möchten Sie meine Antwort hier für eine detaillierte Schritt für Schritt Erklärung des Problems überprüfen.

Benutzen

 scanf("%20s",&filename); 

und bedenke, dass stdin liniengepuffert ist und auf Linux einer ty disziplin folgt

Sie können GNU readline oder ncurses verwenden, wenn Sie eine detailliertere Kontrolle wünschen.

scanf("%s", ...) lässt das \ n die Zeile in der Eingabe beenden. Es verursacht kein Problem für das nächste als scanf (“% s”, …) beginnt mit dem Überspringen von Weiß. scanf("%c", ...) geht nicht und somit liest man das \n .

Übrigens werden Sie wahrscheinlich andere Probleme haben, wenn Sie Leerzeichen in Ihren Dateinamen einfügen ( %s liest sie nicht) und wenn Sie zu lange Namen eingeben (% s hat keine Beschränkungen für die Eingabedauer).

Eine Lösung für das Problem, das Sie beschwert haben (aber nicht das andere), ist die Verwendung von scanf(" %c", ...) (siehe das Leerzeichen, bevor %c ? scanf schwierig zu verwenden ist), wobei weiße Leerzeichen übersprungen werden.

 scanf("%s",&filename); 

entfernen Sie auch

scanf.c: 13: Warnung: Format ‘% s’ erwartet Typ ‘char ‘, aber Argument 2 hat den Typ ‘char ( ) [20u]’

Der bessere Weg, um dieses Problem zu lösen, das ich gefunden habe, wird hier erklärt .

Es empfiehlt sich, eine alternative Art der Eingabe zu verwenden, und es wird sehr gut erklärt.

Ich benutze immer diese function, um Benutzereingaben zu erhalten.

 char * read_line (char * buf, size_t length) { /**** Copyright de home.datacomm.ch/t_wolf/tw/c/getting_input.html#skip Read at most 'length'-1 characters from the file 'f' into 'buf' and zero-terminate this character sequence. If the line contains more characters, discard the rest. */ char *p; if ((p = fgets (buf, length, stdin))) { size_t last = strlen (buf) - 1; if (buf[last] == '\n') { /**** Discard the trailing newline */ buf[last] = '\0'; } else { /**** There's no newline in the buffer, therefore there must be more characters on that line: discard them! */ fscanf (stdin, "%*[^\n]"); /**** And also discard the newline... */ (void) fgetc (stdin); } /* end if */ } /* end if */ return p; } /* end read_line */ 

Alte Antwort

Ich habe diese Art von Problemen mit dieser Regel behoben:

 // first I get what I want. c = getchar(); // but after any user input I clear the input buffer // until the \n character: while (getchar() != '\n'); // this also discard any extra (unexpected) character. 

Wenn Sie dies nach irgendeiner Eingabe machen, sollte es kein Problem geben.