scanf()函数无法工作?

5
这可能是一个简单的问题,但我搜了很多资料仍未解决。我用gcc编译以下代码片段,并从终端运行程序。然而程序不允许输入整数和字符,也不等待输入字符?有没有人能够帮助我呢?先谢谢啦!
#include <stdio.h>

int main()
{

  char c;
  int i;

  // a
  printf("i: ");
  fflush(stdin); scanf("%d", &i);

  // b
  printf("c: ");
  fflush(stdin); scanf("%c", &c);

  return 0;

}


3
fflush(stdin)会导致未定义的行为,不要使用它。 - Crowman
你是否给输入加上了回车键? - Arlie Stephens
1
输入流上未定义fflush。太糟糕了,一些C书籍实际上鼓励这样做。 - digital_revenant
它有什么作用?代码片段以scanf()结束,因此变量c没有被使用。实际上,对于i也是一样的。请注意,如果输入是终端,则scanf()解析非常依赖终端的stty设置。 - ash
5个回答

8

%d会一直读取连续的数字,直到遇到非数字字符。而%c则只会读取一个字符。可能你输入了一个数字(多个数字字符),接着又输入了一个换行符。这时%c会读取该换行符。你可能本意是想用fflush(stdin);来清除尚未读取的所有内容,但不幸的是,这是未定义行为

解决方案是在读取字符前先清除所有空白字符:

scanf(" %c", &c);

请注意开头的空格。这意味着要丢弃所有的空白字符。

这正是我所做的:输入一个数字,然后换行。现在它可以工作了!非常感谢! - dangnam2910

2

不要使用 fflush(stdin); scanf("%c", &c);

1. 使用带有额外空格的scanf函数

scanf(" %c",&c); 

或者

2.使用getchar()两次,第一次读入输入整数后输入的'\n',第二次会要求您提供输入值c:

getchar();
c=getchar();

would help you.


2
你可以使用getchar()函数来实现你想要的效果。
或者通过使用以下方式消耗多余的换行符:
 scanf(" %c", &c);
  ^^^   <------------Note the space

原因:您接下来的scanf用于读取字符时只读取/消耗换行符,因此不会等待用户输入


scanf("%c", &c); 替换为 c = getchar(); 对我来说显示了相同的行为。 - icktoofay
我知道,但我想弄清楚在这种情况下它为什么不起作用。此外,当我改变//a和//b的顺序时,它就起作用了。 - dangnam2910
你下一个用于读取字符的 scanf 函数会读取/消耗掉换行符,因此永远不会等待用户输入。 - Rahul Tripathi
@dangnam2910:我更新了我的回答并附上了原因。希望这样更清楚明白了!!! - Rahul Tripathi

1

首先,scanf只有在正确使用时才能正常工作。我认为以下代码可以满足您的需求。标准输出会被刷新,以便提示用户输入整数或字符。使用%1s可以允许包括\n在内的空格。

int main()
{

  char c[2];
  int i;

  printf("i: ");
  fflush(stdout);
  scanf("%d", &i);

  printf("c: ");
  fflush(stdout);
  scanf("%1s", &c);

  printf("\ni = %d, c = %c", i, c[0]);

  return 0;

}

这段代码在Eclipse/Microsoft C编译器上进行了测试/运行。


1

fflush()不能保证做任何事情,gcc/g++也不会。在Linux上是这样的。

我曾认为我发明了以下方式来清空行尾...直到我在ISO C规范中看到它作为一个例子(90或99...忘记了,但无论如何已经存在很长时间了...我打赌大多数读者在这里之前都看过它)。

scanf("%*[^\n]%*c"); /* 丢弃所有字符直到下一个换行符 */

您可以将其放入自己的“flush”函数中以节省输入或粘贴的时间。

您仍然应该遵循建议,在scanf(" %c", &c);中加一个空格。

这将耐心地等待非空白字符,以防有前导空格或连续按两次回车键。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接