gpt4 book ai didi

c - 为什么这个c程序会陷入死循环?

转载 作者:太空宇宙 更新时间:2023-11-04 00:59:55 24 4
gpt4 key购买 nike

#include <stdio.h>

int main()
{
int sum=0;
char s[10];

while(scanf("%[^\n]s", s)!=EOF)
{
printf("%s", s);

}

return 0;
}

对于任何字符串输入,这个 while 循环都会陷入无限循环。

最佳答案

给定

while(scanf("%[^\n]s", s)!=EOF)
{
printf("%s", s);
}

你问 “为什么这个 c 程序会陷入无限循环?”

因此,您必须了解scanf() 的工作原理。 scanf() 使用您的格式字符串来解析来自 stdin 的输入,这是一个逐个字符传送的流

假设您在 stdin 中有以下内容:

foo\n
bar\n
<<EOF>>

现在你的格式字符串有这个转换 %[^\n] 这意味着“匹配除换行符之外的任何内容并复制到字符缓冲区”。它后面的 s 只是一个文字 s 因为它前面没有 % ...所以它会匹配一个文字 s 如果有的话。换句话说,这里无关紧要。

现在,第一次调用您的 scanf() 时,它将匹配 foo 并使用它。它返回 1 因为它匹配了一个元素。之后,stdin 看起来像这样:

\n
bar\n
<<EOF>>

注意不匹配的换行符仍然存在。您的下一个调用再次以格式字符串开始以匹配除换行符之外的任何内容,但下一个字符是换行符。 scanf() 不匹配任何内容,因此返回 0。它无法返回 EOF,因为如您所见,EOF 尚未到达。这是你的无限循环。

因此,您必须修复您的格式字符串。首先,删除从不匹配任何内容的 s。这里并没有真正的伤害,但它仍然是错误的。然后,您可以利用 scanf()空白匹配。空格是空格制表符换行符。如果您的格式字符串包含空格,scanf() 将匹配尽可能多的空格(也可以没有空格)。因此,一个简单的解决方法是只用一个空格开始你的格式字符串,这将“吃掉”剩下的换行符:

while(scanf(" %[^\n]", s)!=EOF)
{
printf("%s", s);
}

现在这仍然是危险代码,因为[^\n] 匹配任意数量的字符,只要没有换行符,但您的缓冲区只有空间9 个字符加上终止 0。所以你必须告诉 scanf() 不要匹配超过这个限制,这可以通过将数字放在 % 和转换规范之间来完成:

while(scanf(" %9[^\n]", s)!=EOF)
{
printf("%s", s);
}

此代码将以安全的方式执行您想要的操作,但假设您想要匹配更具体的内容,例如数字,你会得到一些意想不到的输入:通过等待 EOF,你会再次陷入无限循环,因为有不匹配的输入,所以你永远无法到达 EOF (与上面不匹配的换行符一样)。因此,请始终检查成功匹配的数量。在这里你期望只有一个匹配,所以循环应该是这样的:

while (scanf(" %9[^\n]", s) == 1)
{
printf("%s", s);
}

实际上,要读取整行,您不需要scanf(),只使用fgets() 会更容易。您的代码可能看起来像这样简单(换行符也将读入 s):

while (fgets(s, 10, stdin))
{
printf("%s", s);
}

注意此处的第二个参数 10:fgets() 自动计算终止字符 0,因此您只需为其指定大小你的缓冲区。

最后的提示:当没有格式化时,如果不使用 printf(),这可能更简单:

while (fgets(s, 10, stdin))
{
fputs(s, stdout);
}

关于c - 为什么这个c程序会陷入死循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44410075/

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