C 从控制台读取字符
我编写了一个控制台应用程序,它对int执行多个scanf 然后,我执行getchar:C 从控制台读取字符,c,scanf,getchar,C,Scanf,Getchar,我编写了一个控制台应用程序,它对int执行多个scanf 然后,我执行getchar: int x,y; char c; printf("x:\n"); scanf("%d",&x); printf("y:\n"); scanf("%d",&y); c = getchar(); 因此,尽管输入为: 1 2 a 如何解决这个问题?这是因为scanf在输入流中留下您键入的换行符。试一试 do c = getchar(); while (isspace(c)); 而不是
int x,y;
char c;
printf("x:\n");
scanf("%d",&x);
printf("y:\n");
scanf("%d",&y);
c = getchar();
因此,尽管输入为:
1
2
a
如何解决这个问题?这是因为
scanf
在输入流中留下您键入的换行符。试一试
do
c = getchar();
while (isspace(c));
而不是
c = getchar();
首先,
scanf
应为scanf(“%d\n”和&x)代码>或y。这应该能奏效
调用fflush(stdin)
在scanf
之后,丢弃scanf
留下的输入缓冲区中任何不必要的字符(如\r\n)
编辑:正如评论中提到的fflush
解决方案可能存在可移植性问题,所以这里是我的第二个建议。根本不要使用scanf
,而是使用fgets
和sscanf
的组合来完成这项工作。这是一种更安全、更简单的方法,因为它允许处理错误的输入情况
int x,y;
char c;
char buffer[80];
printf("x:\n");
if (NULL == fgets(buffer, 80, stdin) || 1 != sscanf(buffer, "%d", &x))
{
printf("wrong input");
}
printf("y:\n");
if (NULL == fgets(buffer, 80, stdin) || 1 != sscanf(buffer, "%d", &y))
{
printf("wrong input");
}
c = getchar();
清除所需字符之前的任何空间并忽略剩余字符的方法如下
do {
c = getchar();
} while (isspace(c));
while (getchar() != '\n');
您可以使用fflush函数清除缓冲区中的任何剩余内容,作为先前comand line输入的结果:
fflush(stdin);
getchar()
返回int
,而不是char
@unwind-“从标准输入(stdin)返回下一个字符。”-ascii for charIt不起作用:输入1后,它不写“y:”(参见更新的示例),但等待第二个数字,并且仅在它写“y:”-1fflush(stdin)后才起作用
未定义。甚至(定义这样一个构造的人)说(尽管是在一个隐藏的位置)它是一个扩展:“//fflush on input stream是对C标准的扩展”。@pmg:True!(就连我也经常指出这一点)。这在SO上出现了很多,但是它可以在MSDN支持下工作(您已经链接了页面),所以<代码>“对于输入流,fflush()将丢弃已从基础文件中提取但尚未被应用程序使用的任何缓冲数据……标准未指定输入流的行为。大多数其他实现的行为与Linux相同。”
…那么在代码中使用它有多糟糕呢?下面的文本略有不同:它根本没有提到应用程序。我根本不喜欢POSIX.1-2008的描述。Linux、Windows和POSIX(有所有的注意事项)还不足以让我称之为portable。@other.anon.coward:还有,当你可以很容易地实现更多的实现时,为什么你会愿意将自己限制在Linux、Windows和POSIX(有所有的注意事项)?@pmg:关于可移植性,你绝对是对的!但是,如果我在支持Linux的平台上的实现中限制这个调用,我可以很好地将它与诸如#ifdef Linux
之类的宏一起使用(可能的话,可以使用诸如gcc之类的C扩展)。正如您所提到的,最好遵守标准。谢谢你的见解fflush(stdin)
根据C标准调用未定义的行为,尽管它在某些系统(实现)上定义良好,但为了提高可移植性,最好避免使用它。