[英]EOF - scanf and printf
我想在这里做一个简单的练习,但是我需要先了解EOF的工作原理。
void main()
{
char s1[1000];
while (scanf("%s", s1)!=EOF)
;
printf("%s",s1);
}
想法是在输入中包含多行,并显示它们。
我的问题是,如果我把
Hello World
This is stackoverflow
调用printf时,仅打印
stackoverflow
为什么不打印所有内容,如何打印?
问候
删除分号;
:
while (scanf("%s", s1)!=EOF)
printf("%s",s1);
请注意,这仍然会在文件结尾显示奇怪的行为,具体取决于它的结尾方式。 此外,它将输入拆分为单词,这些单词由空格或换行符分隔。 您可能需要简单地分成几行。
因此,例如,可能会更好地为您服务:
while (gets(s1)!=NULL)
puts(s1);
此代码片段逐行读取您的输入,直到文件结束。
要读取所有内容(或缓冲区可以容纳的最大内容),可以使用:
char s1[1000] = "";
fread(s1, sizeof(s1) - 1, 1, stdin);
puts(s1);
但是,我首选的读取文本文件的方法是:
using namespace std;
string line;
while (getline(cin, line))
{
cout << line << endl;
}
那是因为通常我要逐行处理文件,而getline
和string
确保行缓冲区始终足够大。
您可能想要这样:
char s1[1000][20];
int i = 0 ;
while (!feof(stdin))
fgets(s1[i++], 20, stdin) ;
int j ;
for (j = 0; j < i; j++)
printf("%s\n", s1[j]);
在这里,您最多可以输入1000行,最长19个字符。
您所拥有的是一个循环,该循环将单词读入缓冲区,直到到达EOF(对这些单词不执行任何操作),然后执行printf
打印缓冲区的内容。 printf
在循环之后(不在循环中),因此在循环完成后执行一次。 那时,缓冲区将包含读取的最后一个字,因此将被打印出来。
EOF
返回测试的意思是“没什么要读取的”,它不一定是文件的结尾(可能是某种错误情况),但是实际上区别可以忽略。 循环直到您的读取函数返回EOF
或NULL
(取决于函数)是一种好习惯。
如果要在读取每个单词时打印它,则需要在循环中放入一个printf
。
如果要存储单词以供以后处理,则需要将它们存储在某个位置。 这意味着声明一些存储空间,或在堆上分配空间,并进行一些簿记以跟踪已使用/分配的空间。
如果要用行而不是单词,则应使用fgets
而不是scanf("%s"
。请注意,当没有更多内容可读取时, fgets
返回NULL
而不是EOF
。
因为它仅打印从文件读取的最后一个内容(“ stackoverflow”)。 这是由while(...);
结束后的分号引起的while(...);
-这意味着您正在执行while(...) { /* do nothing */}
-这可能不是您想要的
另外, printf("%s",s1)!='\\0';
毫无意义。 一方面, printf
返回打印的字符数- '\\0'
是作为字符常量写入的零值。 当然,不使用某种比较就对结果进行!= 0
也是毫无意义的。
如果您想一次读取一行,请使用fgets
而不是scanf
。 当找到空白时, scanf
将停止读取。 fgets
会读取到该行的末尾。
使用fgets()
。 简单而甜美
char buf[1000];
while (fgets(buf, sizeof buf, stdin) != NULL) {
fputs(buf, stdout);
}
这是文件尾在C中的工作方式。输入通道称为输入流 ; 磁盘文件和stdin
都是输入流。 “文件结束”状态是流具有的标志,当您尝试从流中读取该标志时将触发该标志,但是事实证明流中不再有字符,并且永远不会有任何字符更多。 (例如,如果流仍处于活动状态,但仅在等待用户输入,则不将其视为文件结束;读取操作将被阻止)。
流可以具有其他错误状态,因此循环进行直到设置“文件结束”通常是错误的。 如果流确实进入错误状态,则您的循环将永远不会退出(也称为“无限循环”)。
文件结束状态可以通过feof
检查。 但是,某些输入操作也可能会发出错误信号,或者返回而不是返回要读取的实际数据。 这些函数可以返回值EOF
。 通常,在以下两种情况下,这些函数都会返回EOF
:文件结束和流错误。 这与feof
不同, feof
仅在文件结束时返回true
。
例如,如果getchar()
和scanf
是文件末尾,而且流处于错误状态,则它将返回EOF
。
因此可以将getchar()
的结果用作循环条件,但不能feof
。
同样,有时不适合使用scanf() != EOF
作为循环条件。 可能没有流错误,只是您所请求的数据不存在。 例如,如果您扫描"%d"
但流中有字母。 相反,最好检查转换是否成功(scanf返回其执行的转换成功次数)。 然后,当您退出循环时,可以继续调用feof
和ferror
来查看这是由于文件结尾,错误还是仅是意外输入引起的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.