在学习C的过程中,我是一个新手,据我所知,我知道,如果有人给出诸如while (1 == 1)
之类的条件,那么while循环将永远运行。
但是当我读一本书时,我注意到诸如
这样的代码#include<stdio.h>
int main() {
char a;
int started = 0;
puts("Scanning\n");
while (scanf("%s[^\n]",&a) == 1)
{
if (a >= 65 && a <= 90)
{
printf("Char is capital\n");
}
else
{
printf("Not cap.\n");
}
}
puts("Done\n");
return 0;
}
命令行=> char.exe < file.txt
它从标准输入中获取输入,但是scanf返回参数的数目,即1,因此条件应在(1 == 1)
时变为
但是为什么这不是永久循环,而是在读取文件后存在?
谢谢
答案 0 :(得分:2)
在
char a;
...
while (scanf("%s[^\n]",&a) == 1)
您的格式无效,因为在您只想读取char时专用于字符串,因此您将至少在char中写出结尾的空char,从而产生未定义的行为
做
char a;
...
while (scanf(" %c",&a) == 1)
并注意格式中的空格,如果要管理所有字符,请将其删除
在
if (a >= 65 && a <= 90)
使用ASCII码是错误的,它不可读并且与非ASCII不兼容
你可以做
if (a >= 'A' && a <= 'Z')
或更好地使用 isupper (<ctype.h>
),因为它不保证大写字母是连续的
您的 printf 可以替换为 puts ,删除字符串中的\ n或 fputs ,对于没有 printf 打印一个简单的字符串(没有%和arg)
但是为什么这不是永久循环,而是在读取文件后存在?
scanf 在EOF上不返回1,因此循环在EOF上停止,大约是 scanf 族:
这些函数返回成功匹配和分配的输入项的数量,该数量可以少于所提供的数量,或者在早期匹配失败的情况下甚至为零。
如果在第一次成功转换或匹配失败发生之前达到输入结束,则返回EOF值。如果发生读取错误,也会返回EOF,在这种情况下,将设置流的错误指示符(请参见ferror(3)),并设置errno来指示错误。
答案 1 :(得分:1)
但是为什么这不是永久循环,而是在读取文件后存在?
仅当scanf
每次调用返回1时,它才会无限循环。循环在函数第一次返回不同结果时终止。 *
scanf
的返回值传达 成功 已扫描和分配的输入字段的数量,并且在某些情况下还传达有关I / O错误的信息。特别是,scanf
将在匹配任何字段之前到达宏EOF
的值(如果它到达输入的末尾)。 EOF
不等于1。
* 提供了该程序的行为的良好定义。由于注释和其他答案中所述的原因,您的程序不是。
答案 2 :(得分:0)
函数scanf返回以下值:
>0
成功转换和分配的项目数。0-未分配任何项目。
<0-遇到读取错误,或者在读取错误之前达到文件结尾(EOF) 进行了分配。
答案 3 :(得分:0)
&a
表示您正在尝试读取堆栈变量中的整行。
但是为什么这不是永久循环,而是在读取文件后存在?
尝试读取堆栈变量中的文件将导致堆栈崩溃,并且程序将崩溃。
在Internet上的C中寻找不同的存储类型和内存管理。 a
是在程序堆栈上分配的字符变量,仅假定存储一个字符。如果使用它的地址并尝试放置更多数据,则它将破坏相邻的堆栈内存/变量,直到OS检测到该内存并杀死程序为止。您的格式表示它将读取整行,即直到换行为止。
scanf
仍将返回1,但它将尝试将该行存储在a
的地址中。
您是否像这样运行它?
cat <your file>| ./a.out
分配足够大的缓冲区,例如char a[4096];
并将a
传递为
while(scanf("%s[^\n]", a) == 1)
现在注意a
现在是一个数组,不需要前面的&
。文件结束后,循环仍将退出,但仍在EOF上。如果新行直到4Kb才出现,请尝试使用小于4 Kb的文件,这是最坏的情况。
读取更大文件/行的规定似乎超出了您的实验范围。
工作代码
#include<stdio.h>
int main() {
char a[4096];
int started = 0;
puts("Scanning\n");
while (scanf("%s[^\n]", a) == 1)
{
if (a >= 65 && a <= 90)
{
printf("Char is capital\n");
}
else
{
printf("Not cap.\n");
}
}
puts("Done\n");
return 0;
}
答案 4 :(得分:0)
输入字母时,条件(1==1)
成立,并且while
循环的主体被迭代。
在while
循环迭代之后,它进入下一个字母。 scanf
等到您输入下一个字符。
再次满足条件(1==1)
。
此循环是不确定的循环,您可以继续输入字母,而永远不会到达puts
语句。