38

各行に文字列があるテキストファイルがあります。テキストファイルの各行の番号をインクリメントしたいのですが、ファイルの最後に到達したら、明らかに停止する必要があります。EOFについて調べてみましたが、使い方がよくわかりませんでした。

whileループが必要だと思いますが、その方法がわかりません。

4

4 に答える 4

101

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を返さないため、人々が考えるようには機能しません。その結果、ループの実行回数が多すぎて、悲しみを引き起こす場合と引き起こさない場合があります。

于 2009-12-02T22:55:01.907 に答える
13

考えられるCループの1つは次のとおりです。

#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にまだ到達していないという信念で、間違ったタイミングで呼び出して何かを2回処理するのは非常に簡単です。

避けるべき落とし穴:charcのタイプに使用します。getcharにキャストされた次の文字を返し、次に。unsigned charにキャストしintます。これは、ほとんどの[正常な]プラットフォームでは、の値EOFと有効な " char"値がc重複しないため、誤っEOFて'normal'を検出することがないことを意味しますchar

于 2009-12-02T21:51:57.310 に答える
0

ファイルから読み取った後、EOFを確認する必要があります。

fscanf_s                   // read from file
while(condition)           // check EOF
{
   fscanf_s               // read from file
}
于 2014-06-05T12:15:13.533 に答える
0

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);
于 2020-01-19T21:52:43.967 に答える