各行に文字列があるテキストファイルがあります。テキストファイルの各行の番号をインクリメントしたいのですが、ファイルの最後に到達したら、明らかに停止する必要があります。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ループの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回処理するのは非常に簡単です。
避けるべき落とし穴:char
cのタイプに使用します。getchar
にキャストされた次の文字を返し、次に。unsigned char
にキャストしint
ます。これは、ほとんどの[正常な]プラットフォームでは、の値EOF
と有効な " char
"値がc
重複しないため、誤っEOF
て'normal'を検出することがないことを意味しますchar
。
ファイルから読み取った後、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);