c - getchar 的奇怪行为,这是实现定义的行为吗?
问题描述
我正在尝试打印一个整数平方表。目的是编写一个程序,在每 24 个方格后暂停,并要求用户打印 Enter 以继续。这并不太复杂,我已经用 C 语言“完成”了手头的任务。
我的担忧:当我编译和运行以下代码时,会出现一个看似无关紧要(但可以观察到)的小问题:
#include <stdio.h>
int main()
{
int i, n;
printf("This Program prints a table of squares. \n");
printf("Enter number of entries in table: ");
scanf("%d", &n);
for(i = 1; i <= n; i++) {
if((i - 1) % 24 == 0 && i > 1) {
printf("Press Enter to continue...");
while(getchar() != '\n')
;
}
printf("%10d%10d\n", i, i*i);
}
}
我的输出是完美的,正是我想要的,除了24 的第一个倍数(即 24)。出于某种原因,如果我选择一个大的 n,表格将完美打印出来,但只需要我从 48 开始按 Enter,第一个 printf 输出很奇怪,它不需要用户按任何键(更不用说 Enter )。它看起来像这样:
24 576
Press Enter to coninue... 25 625
26 676
但是下次代码使用 printf 时,一切似乎都很完美,我需要按 Enter 继续,因为它应该是..(代码中稍后的健康输出示例以及所有后续的 24 倍数) .
48 2304
Press Enter to coninue...
49 2401
纠正这一点的一件事是,如果我在 for 循环中的 printf 和 while 之间放置了一个额外的 getchar() 函数。所以代码完全一样,除了 for 循环现在看起来像这样:
for(i = 1; i <= n; i++) {
if((i - 1) % 24 == 0 && i > 1) {
printf("Press Enter to continue...");
getchar();
while(getchar() != '\n')
;
}
printf("%10d%10d\n", i, i*i);
}
在这种情况下,代码运行完美。除了从 48 开始我需要按两次 Enter 键。大概这是因为我已经设置了额外的 getchar() 但是为什么我只需要在 i = 24 时按一次 Enter 呢?
我的猜测是这与(i - 1) % 24
论点有关,但我看不出问题出在哪里。这是 KNK C Programming A Modern Approach 第 7 章中的一个问题。我是一名自学成才的程序员。我希望我的问题易于理解,并且它阐明了关于 C 的一些重要内容。这可以被视为实现定义的行为吗?也许在另一台机器上我所描述的不会发生?如果不是,为什么不呢?
解决方案
在调用 之后scanf
,输入缓冲区中会留下一个换行符。这个换行符在第一次调用时被拾取,getchar
导致它跳出while
循环。
您想在scanf
调用后通过循环使用换行符,getchar
直到获得换行符。
scanf("%d", &n);
while (getchar() != '\n');
推荐阅读
- ios - 如何正确换行长文本?
- python - 我想弄清楚将 playerX 移动到屏幕有什么问题?我想移动 playerX += .1 但出现错误?
- python - Python - 从文件夹目录创建字典
- c# - 在 Identity Asp.net core 3 MVC 中创建服务 IUserStore 时出错
- java - 智能支付按钮服务器集成
- r - 闪亮的 RMarkdown 中的奇怪行为
- angular - 我什么时候应该直接在 Angular 应用程序中 DI 注入器?
- lua - Lua 在名称与字符串匹配的实例中获取实例
- windows - 共享文件夹中没有这样的文件或目录
- ios - “kCGContextTypeIOSurface”类型的 CGContext