[英]How to use EOF to run through a text file in C?
我有一個文本文件,每行都有字符串。 我想為文本文件中的每一行增加一個數字,但是當它到達文件末尾時,它顯然需要停止。 我試過對 EOF 進行一些研究,但無法真正理解如何正確使用它。
我假設我需要一個 while 循環,但我不知道該怎么做。
您如何檢測 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
檢查輸入調用的結果是否符合上述適當條件,然后調用feof()
以確定結果是由於遇到 EOF 還是其他一些錯誤。
使用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);
...
}
這種形式並不像人們認為的那樣工作,因為feof()
直到您嘗試讀取文件末尾之后才會返回 true。 結果,循環執行了一次太多,這可能會也可能不會讓您感到悲傷。
一種可能的 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.
*/
}
}
現在,我會忽略feof
和類似的功能。 經驗表明,在錯誤的時間調用它並在認為尚未達到 eof 的情況下兩次處理某事太容易了。
要避免的陷阱:對 c 的類型使用char
。 getchar
將下一個字符轉換為unsigned char
,然后轉換為int
。 這意味着在大多數 [sane] 平台上, EOF
的值和c
有效的“ char
”值不會重疊,因此您永遠不會意外地檢測到“正常” char
EOF
。
從文件讀取后,您應該檢查 EOF。
fscanf_s // read from file
while(condition) // check EOF
{
fscanf_s // read from file
}
我建議您使用 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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.