提问人:Tyler Treat 提问时间:12/3/2009 最后编辑:Ciro Santilli OurBigBook.comTyler Treat 更新时间:1/20/2020 访问量:327986
如何使用EOF在C语言中运行文本文件?
How to use EOF to run through a text file in C?
问:
我有一个文本文件,每行都有字符串。我想为文本文件中的每一行增加一个数字,但是当它到达文件末尾时,它显然需要停止。我尝试对EOF进行一些研究,但无法真正了解如何正确使用它。
我假设我需要一个 while 循环,但我不确定该怎么做。
答:
14赞
CB Bailey
12/3/2009
#1
一个可能的 C 循环是:
#include <stdio.h>
int main()
{
int c;
while ((c = getchar()) != EOF)
{
/*
** Do something with c, such as check against '\n'
** and increment a line counter.
*/
}
}
现在,我会忽略类似的功能。经验表明,在错误的时间调用它并两次处理某些东西,认为 eof 尚未达到,这太容易了。feof
要避免的陷阱:用于 c 的类型。 将下一个字符强制转换为 AN 返回,然后返回到 .这意味着在大多数 [理智] 平台上,中的值和有效的 “” 值不会重叠,因此您永远不会意外检测到 'normal' 。char
getchar
unsigned char
int
EOF
char
c
EOF
char
评论
0赞
streetparade
12/3/2009
看我的答案 我定义了一个 EOF
1赞
CB Bailey
12/3/2009
@streetparade:效果如何?
0赞
caf
12/3/2009
有效的字符值 from 绝不能与任何符合要求的平台上重叠,因为返回 的字符在 (因此是非负数) 的范围内,并且必须为负数。getchar
EOF
getchar
unsigned int
EOF
0赞
CB Bailey
12/3/2009
@caf:我就是这么想的,直到有人向我指出,有 32 个字符和 32 个整数的平台。这意味着 char -> unsigned char -> int 最终可能为负数。因此是“[理智]”。
0赞
caf
12/3/2009
哦,是的,还有关于忽略的好建议 - 根据我的经验,使用该函数几乎总是表明存在错误。在 99% 的情况下,测试最近输入函数调用的返回值就足够且正确。feof
109赞
John Bode
12/3/2009
#2
检测 EOF 的方式取决于用于读取流的内容:
function result on EOF or error
-------- ----------------------
fgets() NULL
fscanf() number of succesful conversions
less than expected
fgetc() EOF
fread() number of elements read
less than expected
检查输入调用的结果是否符合上述适当条件,然后调用以确定结果是由于命中 EOF 还是其他一些错误造成的。feof()
用:fgets()
char buffer[BUFFER_SIZE];
while (fgets(buffer, sizeof buffer, stream) != NULL)
{
// process buffer
}
if (feof(stream))
{
// hit end of file
}
else
{
// some other error interrupted the read
}
用:fscanf()
char buffer[BUFFER_SIZE];
while (fscanf(stream, "%s", buffer) == 1) // expect 1 successful conversion
{
// process buffer
}
if (feof(stream))
{
// hit end of file
}
else
{
// some other error interrupted the read
}
用:fgetc()
int c;
while ((c = fgetc(stream)) != EOF)
{
// process c
}
if (feof(stream))
{
// hit end of file
}
else
{
// some other error interrupted the read
}
用:fread()
char buffer[BUFFER_SIZE];
while (fread(buffer, sizeof buffer, 1, stream) == 1) // expecting 1
// element of size
// BUFFER_SIZE
{
// process buffer
}
if (feof(stream))
{
// hit end of file
}
else
{
// some other error interrupted read
}
请注意,所有这些形式都是相同的:检查读取操作的结果;如果失败,则检查 EOF。你会看到很多例子,比如:
while(!feof(stream))
{
fscanf(stream, "%s", buffer);
...
}
此表单的工作方式与人们想象的不同,因为在您尝试读取文件末尾之前不会返回 true。结果,循环执行一次太多次,这可能会也可能不会给您带来一些悲伤。feof()
评论
1赞
chux - Reinstate Monica
11/7/2015
很好,但这个流行答案的一些建议:1)“函数:EOF结果或错误:成功转换次数少于预期”等同于输入“错误”与格式转换失败。IMO不是正确的分组。建议另一列OTOH,这是一个复杂的功能:2)拼写检查,3)建议“坏代码”,对示例进行评论。fscanf()
while(!feof(stream))
0赞
Nematollah Zarmehi
6/5/2014
#3
您应该在从文件读取后检查 EOF。
fscanf_s // read from file
while(condition) // check EOF
{
fscanf_s // read from file
}
0赞
valerinho
1/20/2020
#4
我建议你使用 fseek-ftell 函数。
FILE *stream = fopen("example.txt", "r");
if(!stream) {
puts("I/O error.\n");
return;
}
fseek(stream, 0, SEEK_END);
long size = ftell(stream);
fseek(stream, 0, SEEK_SET);
while(1) {
if(ftell(stream) == size) {
break;
}
/* INSERT ROUTINE */
}
fclose(stream);
评论