gpt4 book ai didi

c - 为什么输入 '\n' 时包含 getchar() 的循环会退出?

转载 作者:行者123 更新时间:2023-12-03 23:58:38 24 4
gpt4 key购买 nike

我在使用 K&R,它广泛使用 getchar() 作为基础输入。但问题是我无法完全理解它的行为。

下面是一段代码:

#include <stdio.h>

int main() {
char c,i;
char line[10000];
i = 0;

while((c=getchar()) != EOF && c!= '\n') {
line[i++] = c;
}

printf("%s",line);
}

代码按预期工作。

我的问题是:为什么当我按下回车键时它会终止?当我仍在编写输入并且程序位于 c=getchar() 时,它如何知道换行符是终止条件?

我知道这不是默认的 getchar() 行为,如 scanf() 因为当我删除换行条件时,程序不会在换行处终止。 也许我的问题超出了 getchar() 并且是一般问题。

假设我的输入是 Hello 并且我按下回车键。

首先,c 变量变为 'H',它被存储在 line 中,然后是 'e',然后是 ' l',然后是 'l',然后是 'o',然后遇到换行符并终止循环。很好理解。

我想知道为什么它在我按回车后开始读取字符。我希望换行并写更多字符。

最佳答案

理解该代码有两个部分,还有一个错误 chqrlie对修复提出了很好的论据。

第 0 部分:为什么应该使用 intgetchar

进行阅读

正如许多人评论的那样,如果您打算使用 getchar 阅读,使用 char c 是危险的,因为 getchar() 返回有符号整数, 最值得注意的是 EOF - 通常是 #defined as -1 表示文件结束。标准 char may or may not have a sign - 这会使您的程序无法识别 -1/EOF。所以让我们把第一行改成

int c,i; 

第 1 部分:\n 为什么特别

根据man , getchar() 等价于 getc(stdin),后者等价于 fgetc(),不同之处在于它可以实现为评估其流的宏 ( stdin,在这种情况下)不止一次。

重要的是,每次调用它时,它都会消耗其输入中的一个字符。只要有要返回的字符,对 getchar 的每次调用都会返回输入中的 next 字符。如果没有剩余,则返回 EOF

现在,标准输入 stdin 通常是行缓冲的,这意味着程序将无法访问实际字符,直到行以 \n 终止>。您可以使用此程序进行测试:

#include <stdio.h>

int main() {
int c,i;
char line[10000];
i = 0;

while((c=getchar()) != EOF && c!= 'a') { // <-- replaced `\n` with `a`
line[i++] = c;
}

printf("%s",line);
}

如果你运行它,它仍然不会做任何事情,直到 \n 被按下;但是当按下时,输入将在第一个 a (不包含)完成。请注意,之后的输出将是未定义的,因为不能保证之后会有一个 \0 来终止字符串。为了避免这个陷阱,请在最后查看重写的程序。

第 2 部分:为什么循环条件会这样工作

您可以如下重写循环条件。这样可以更轻松地查看正在发生的事情:

// loop condition looks up next char, tests it against EOF and `\n`
while((c=getchar()) != EOF && c!= '\n') { line[i++] = c; }

// loop condition broken up for readability; fully equivalent to above code
while (true) {
c = getchar();
if (c == EOF || c == '\n') {
break; // exit loop
} else {
line [i++] = c;
}
}

结语:改进的代码

#include <stdio.h>
#define BUFSIZE 10000

int main() {
char line[BUFSIZE]; // avoid magic number
int c, i = 0; // initialize at point of declaration

while (i<BUFSIZE-1 // avoid buffer overflow
&& (c=getchar()) != EOF // do not read past EOF
&& c!= '\n') { // do not read past end-of-line
line[i++] = c;
}

line[i++] = 0; // ensure that the string is null-terminated
printf("%s",line);
return 0; // explicitly return "no error"
}

关于c - 为什么输入 '\n' 时包含 getchar() 的循环会退出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65869283/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com