在另一个字符串输入函数之后调用scanf()会创建幻像输入

时间:2013-07-12 12:19:09

标签: c scanf

这是一个小程序:

#include <stdio.h>

int main() {
  char str[21], choice[21]; int size;
  while(1){
    printf("$ ");
    fgets(str, 20, stdin);
    printf("Entered string: %s", str);
    if(str[0] == 'q') {
      printf("You sure? (y/n) ");
      scanf("%s", choice);
      if(choice[0] == 'y' || choice[0] == 'Y')
        break;
    }
  }
  return 0;
}

它使用fgets()读取字符串。如果字符串以q开头,则确认用户是否要退出,如果用户键入y则退出。

当我运行它并输入q时,会发生这种情况:

$ q
Entered string: q
You sure? (y/n) n
$ Entered string: 
$ 

请注意$ Entered string:。很明显,fgets()有一个空字符或其他东西作为输入,即使我没有输入任何内容。

发生了什么事?

3 个答案:

答案 0 :(得分:2)

这是因为scanf调用会读取一个字符,但会将换行符保留在缓冲区中。因此,当您下次调用fgets时,会发现一个换行符并读取它,导致读取空行。

解决方案看似简单:在scanf调用格式后面加一个空格:

scanf("%s ", choice);
/*       ^    */
/*       |    */
/* Note space */

这会导致scanf读取并丢弃所有训练空白,包括换行符。

答案 1 :(得分:2)

如其他答案scanf中所述,调用会将新行留在输入缓冲区中,您也可以在scanf之后使用getchar(),如下所示:

scanf("%20s", choice);// always remember( & good) to include field width 
                      // in scanf while reading

否则它会在大字符串`

的情况下覆盖缓冲区
getchar();  //this will eat up the newline 

此外,你还应该使用这样的fgets:

fgets(str,sizeof str, stdin); //Its better 

答案 2 :(得分:0)

使用特定尺寸char choice [1]

的'char'

OR

char c[1];
c = getchar();
if(c[0] == 'y' || c[1] == 'y'){
 // DO SOMETHING
}