【发布时间】:2013-11-10 14:17:01
【问题描述】:
我刚刚学习用 C 编程,对 scanf 和 getchar 发生的事情有点困惑。我知道使用scanf("%d", &i) 之类的东西会读取一个整数输入,但会在输入缓冲区中留下以下换行符(这就是为什么在@987654327 之后使用getchar 之前必须通过查找getchar() == '\n' 来清除输入缓冲区的原因@调用。
这是我的简单(不正确)程序,它读取一个整数,然后输入一个字符,并将它们打印回用户:
int main(void)
{
int i;
printf("Enter an integer: ");
scanf("%d\n", &i);
printf("Enter a char: ");
char ch = getchar();
printf("You entered integer: %d\nYou entered character: %c\n", i, ch);
return 0;
}
如果我在我的scanf 格式字符串中保留换行符(所以只有"%d"),那么只要用户输入一个整数并点击输入,该整数就会被读取并存储在i,程序将继续执行(“输入一个字符:”立即打印,ch存储换行符)。
但是,使用 "%d\n" 的格式字符串时,我遇到了意外行为。当用户输入一个整数并按回车键时,我希望打印“输入一个字符:”。相反,您可以继续按 Enter 键,直到您决定输入不同的字符之前什么都不会发生。所以你可以输入“10”,按回车键 6 次,然后输入“d”,getchar() 会“正确”读取。整个程序的输出应该是这样的
Enter an integer: 10
d
Enter a char: You entered integer: 10
You entered character: d
为什么我的程序直到输入一个字符才会停止?我的第二个printf 函数似乎在调用getchar 之后被调用,这似乎很奇怪(因为读取的字符是在“输入字符:”打印之前输入的)。
任何帮助将不胜感激。我只是想进一步了解 C 中的这种细微差别。
【问题讨论】:
-
不要使用
scanf()。如果你不完全知道它是如何工作的,那就是为什么。如果您确实知道它是如何工作的,那么这就是原因。 We can have nicer things. -
@H2CO3 明白了。这只是一个练习。我试图进一步了解
scanf()是如何处理空白的。在这种情况下,换行符。 -
是的,这很好,我绝对不想阻止你学习。正如人们应该了解 C++ 中的原始指针(尽管它通常不使用)一样,您也应该了解
scanf()。我只是警告说,它通常不是在生产中使用的最佳选择。 -
@H2CO3 很公平,这也是我读过的(我相信我正在读的书中提到过)。但它肯定有它的用途(在一些非常罕见的情况下,
goto也是如此)。什么是更安全的替代品?我超越了我目前的理解,但我 认为scanf在与正则表达式混合时可以做一些花哨的输入格式。还有更安全的选择吗? -
我最喜欢的概念是:一个功能 - 一个目的。试图做不止一件事的功能本质上是有缺陷的。
scanf()尝试同时进行 I/O 和解析。不太好。如果可以的话,最好将 I/O 部分(fgets()、getchar()、getline()、fread()、read()等)与解析部分分开。对于解析,还有一些有用的标准库函数,例如strtok_r()、str[r]chr()、strstr(),也许最终是sscanf()。