问题
#define len 100
char sourceString[len];
char command;
int main(void)
{
while (1)
{
printf("\nEnter source: ");
fgets(sourceString, len, stdin); // this gets skipped on second loop.
printf("\nEnter command: ");
scanf(" %c", command)
switch (command)
{
case 'A':
printf("%s", sourceString);
break;
case 'B':
printf("filler");
break;
default:
break;
}
}
return 0;
}
Whether im using fgets or scanf the string always gets skipped on the second loop. I tried adding a space to the second scanf " %c" but it still skips the string input, yes im trying to read a line and then a character.
回答1:
After the call of scanf insert the following calls
scanf( "%*[^\n]" );
scanf( "%*c" );
to remove the new line character '\n' from the input buffer.
回答2:
Use fgets()
for both and just derefernce the array holding command
to get the first character -- ensures a complete line is read.
Your problem is scanf()
is leaving the '\n'
in your input stream which on your next iteration is taken by fgets()
(since fgets()
reads up to and including the next '\n'
in the input stream). This makes it appear like fgets()
was skipped -- it wasn't it just read the '\n'
left by scanf()
.
#define len 100
int main(void)
{
char sourceString[len]; /* don't use global variables */
char command[len];
while (1)
{
printf ("\nEnter source: ");
fgets (sourceString, len, stdin); // this no longer skipped in loop.
printf("\nEnter command: ");
fgets (command, len, stdin);
switch (*command)
{
case 'A':
printf("%s", sourceString);
break;
case 'B':
printf("filler");
break;
default:
break;
}
}
return 0;
}
(note: you must always check the return of EVERY input function call -- that is left to you. See Henry Spencer's 10 Commandments for C Programmers - No. 6 "Ye be warned...")
Let me know if you have further questions.
回答3:
The problem is that the fgets() function in the second loop captures '\n', which is when you press enter after you type input to the scanf() of the first loop. There is a solution to overcome this problem which is to add a getchar() function after scanf() so that it captures the '\n' instead of the fgets() of the second loop and the following loops. Here is a sample program :
while (1)
{
printf("\nEnter source: ");
fgets(sourceString, len, stdin);
printf("\nEnter command: ");
scanf(" %c", &command);
getchar();
/* Rest of the program would follow */
}
回答4:
Here are the steps that explain the observed behavior:
printf("\nEnter source: ");
: the prompt is printed.fgets(sourceString, len, stdin);
an input line is read, you should test the return value to ensurefgets()
succeeded.printf("\nEnter command: ");
a line is skipped and a new prompt is output.scanf(" %c", command)
any initial white space is skipped (including pending newlines) and a single character is read. Note however that the user must type enter for this character to be made available to the program because the terminal is most likely in cooked mode, ie: line buffered. Also note that you must pass the address ofchar
variablecommand
or undefined behavior will ensue.- the
switch
selects what gets done and the loop skips to the next iteration printf("\nEnter source: ");
: the prompt is printed.fgets(sourceString, len, stdin);
fgets()
returns immediately with an empty line because the newline typed above is still pending in the input buffer. This is the problem.
You can fix this behavior by discarding the rest of the pending line after the character is read with:
scanf("%*[^\n]"); // read any characters except newline
scanf("%*1[\n]"); // read at most 1 newline character
You must use 2 separate calls to scanf()
because the first conversion would fail if there are no characters before the newline.
#incude <stdio.h>
#define LEN 100
int main(void) {
char sourceString[LEN];
char command;
for (;;) {
printf("\nEnter source: ");
if (!fgets(sourceString, len, stdin))
break;
printf("\nEnter command: ");
/* read a single non blank character and discard the rest of the line */
if (scanf(" %c%*[^\n]", &command) != 1)
break;
/* discard the pending newline if any */
scanf("%*1[\n]"); // of just getchar()
switch (command) {
case 'A':
printf("%s", sourceString);
break;
case 'B':
printf("filler");
break;
default:
break;
}
}
return 0;
}
来源:https://stackoverflow.com/questions/60780394/scanf-skipped-after-loop-in-c