scanf在C [重复]中循环后跳过

问题描述 投票:1回答:4
#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; }
无论im是否使用fgets或scanf,字符串总是在第二个循环中被跳过。我尝试在第二个scanf“%c”上添加一个空格,但是它仍然跳过字符串输入,是的,我试图读取一行然后是一个字符。
c while-loop scanf
4个回答
1
投票
在scanf调用之后,插入以下调用

scanf( "%*[^\n]" ); scanf( "%*c" );

从输入缓冲区中删除换行符'\ n'。

0
投票
两者都使用fgets(),只是取消引用持有command的数组以获取第一个字符-确保读取完整行。

[您的问题是scanf()'\n'留在您的输入流中,下一次迭代将由fgets()进行(因为fgets()读取并包含输入流中的下一个'\n')。这使它看起来像被跳过了fgets()-并非只是读取了'\n'留下的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:您必须始终检查每个输入函数调用的返回-留给您。请参阅Henry Spencer's 10 Commandments for C Programmers - No. 6 “被警告...”)]

让我知道是否还有其他问题。

0
投票
问题是第二个循环中的fgets()函数捕获了'\ n',这是在第一个循环的scanf()中键入输入后按Enter键的结果。解决此问题的解决方案是在scanf()之后添加getchar()函数,以便捕获第二个循环和后续循环的'\ n'而不是fgets()。这是一个示例程序:

while (1) { printf("\nEnter source: "); fgets(sourceString, len, stdin); printf("\nEnter command: "); scanf(" %c", &command); getchar(); /* Rest of the program would follow */ }


0
投票
以下是解释观察到的行为的步骤:

    [printf("\nEnter source: ");:显示提示。
  • fgets(sourceString, len, stdin);读取输入行,您应该测试返回值以确保fgets()成功。
  • printf("\nEnter command: ");跳过一行并输出新的提示。
  • scanf(" %c", command)会跳过所有初始空白(包括待处理的换行符),并读取单个字符。但是请注意,由于终端很可能处于
  • cooked模式,即:行缓冲,因此用户必须键入enter才能使该字符可用于程序。另请注意,您必须传递char变量command的地址,否则将发生未定义的行为。
  • switch选择要完成的操作,然后循环跳至下一个迭代
  • [printf("\nEnter source: ");:显示提示。
  • fgets(sourceString, len, stdin); fgets()立即返回空行,因为上面键入的换行符仍在输入缓冲区中挂起。这是问题。
  • 您可以通过读取字符后丢弃其余的待处理行来解决此问题:

    scanf("%*[^\n]"); // read any characters except newline scanf("%*1[\n]"); // read at most 1 newline character

    您必须对scanf()使用2个单独的调用,因为如果换行符前没有字符,则第一次转换将失败。

    #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; }

  • © www.soinside.com 2019 - 2024. All rights reserved.