问题
This is the basic code to a program I am writing to practise using files in C. I am trying to detect whether the output file already exists and if it does exist I want to ask the user if they would like to overwrite it or not. This is the reason that I have first opened the outfilename file in with fopen(outfilename,\"r\"); as opposed to fopen(outfilename,\"w\");.
It detects the case of the file not existing, however, if it does exist it executes the printf(\"Output file already exists, overwrite (y/n):\"); statement but completely ignores the scanf(\"%c\",&yn); statement!
The printf at the end of the program reads \"yn=0\" if the file doesn\'t exist and just \"yn=\" if it does exist. Can anybody help me?
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <string.h>
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;
}
回答1:
printf("Please enter an output filename: ");
scanf("%s",&outfilename);
When you enter the second string and hit the ENTER key, a string and a character are placed in the input buffer, they are namely: the entered string and the newline character.The string gets consumed by the scanf
but the newline remains in the input buffer.
Further,
scanf("%c",&yn);
Your next scanf
for reading the character just reads/consumes the newline and hence never waits for user input.
Solution is to consume the extra newline by using:
scanf(" %c", &yn);
^^^ <------------Note the space
Or by using getchar()
You may want to check out my answer here for a detailed step by step explanation of the problem.
回答2:
Use
scanf("%20s",&filename);
and remember that stdin is line buffered and on Linux is following a tty discipline
You could use GNU readline or ncurses if you want more detailed control.
回答3:
scanf("%s", ...)
leaves the \n terminating the line in the input. It isn't causing a problem for the next one as scanf("%s", ...) starts by skipping whites. scanf("%c", ...)
doesn't and thus you read the \n
.
BTW You'll probably meet other problems is you put spaces in your file name (%s
doesn't read them) and if you enter too long names (%s has no input length limitations).
One solution for the problem you complained (but not the other one) is to use scanf(" %c", ...)
(see the space before %c
? scanf
is tricky to use) which starts by skipping white spaces.
回答4:
scanf("%s",&filename);
also remove the &
scanf.c:13: warning: format '%s' expects type 'char ', but argument 2 has type 'char ()[20u]'
回答5:
The better way to handle this problem I found is explained here.
It recomends to use an alternative way of handle input and is very well explained.
I use always this function to get user input.
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 */
Old Answer
I fixed this sort of problems with this rule:
// 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.
If you make this after any input, there should be not problem.
来源:https://stackoverflow.com/questions/8464620/program-doesnt-wait-for-user-input-with-scanfc-yn