feof()
ループ条件として使用しないでください。ファイルの最後を超えて読み込もうとするまで true を返しません。つまり、ループが何度も実行されます。入力呼び出しの結果 ( または を使用するかどうかfgets()
)をチェックfscanf()
して、成功したかどうかを確認してから、エラー状態が発生したかどうかを確認します。 feof()
if (fgets(buffer, sizeof buffer, stream) != NULL)
{
// process the input buffer
}
else if (feof(stream)
{
// handle end of file
}
else
{
// handle read error other than EOF
}
fgets()
個々の文字ではなく文字列全体を読み取るため、文字列内の個々の文字のアドレスを渡したくありません。代わりに次のように呼び出します。
if (fgets(list[i], sizeof list[i], stream) != NULL)
{
// process input address
}
そして今、配列とポインターについてのボードのいつもの熱弁のために...
配列式がほとんどのコンテキストで出現する場合、式の型は "T の N 要素配列" から "T へのポインター" に暗黙的に変換され、式の値は配列の最初の要素のアドレスになります。この規則の例外は、配列式がsizeof
or&
演算子のオペランドである場合、または宣言で初期化子として使用されている文字列リテラルである場合です。「配列とポインタは同じものだ」と人々が言うのを聞くとき、彼らはそのルールを混乱させています。配列とポインターはまったく別物ですが、状況によっては同じ意味で使用できます。
上記のコードでは、最初の引数として fgets() に何も装飾 (演算子list[i]
など) なしで渡したことに注意してください。&
の型list[i]
は「char の 12 要素配列」ですが、このコンテキストでは暗黙的に「char へのポインタ」型に変換され、値は のアドレスになりますlist[i][0]
。sizeof
同じ式を演算子にも渡したことに注意してください。その場合、配列式の型はポインター型に変換され ず、sizeof 演算子は配列型のバイト数 (12) を返します。
それを釘付けにするだけです:
式の型 暗黙的に変換される
---------- ---- ----
list char [100][12] char (*)[12] (char の 12 要素配列へのポインタ)
リスト[i] char [12] char *
list[i][j] char 該当なし
これが意味することはfgets()
、次の 12 文字まで読み取り (最初に改行または EOF にヒットしない場合)、それをlist[i][0]
. fgets()
文字列の末尾に終了ヌル文字 (0) を書き込むことに注意してください。また、 が改行にfgets()
遭遇し、それと終端の nul のためのスペースがターゲット配列にある場合、は終端の改行を nul 文字の前に格納することにも注意してください。したがって、入力ファイルに次のような行がある場合fgets()
1.1.1.1\n
次に、読み取り後の入力バッファーの内容は、ランダムな値"1.1.1.1\n\0xxx"
になります。x
そこに改行が必要ない場合は、strchr()
関数を使用して検索し、0 で上書きできます。
char *newline;
...
if ((newline = strchr(input[i], '\n')) != NULL)
{
*newline = 0;
}
次の改行で停止し、fgets()
入力バッファーのサイズが 12 文字であるため、ファイル内の次の入力文字として改行がある状況に遭遇する可能性があります。その場合、fgets()
その改行のみが入力バッファーに書き込まれるため、空のエントリがいくつかありますが、これはおそらく必要なものではありません。そのような状況を避けるために、入力バッファーに余分なバイトを追加したい場合があります。
すべてを一緒に入れて:
char list[100][13];
...
for (i = 0; i < 100; ++)
{
if (fgets(list[i], sizeof list[i], stream) != NULL)
{
char *newline = strchr(list[i], '\n');
if (newline != NULL)
*newline = 0;
printf("Read address \"%s\"\n", list[i]);
count++;
}
else if (feof(stream))
{
printf("Reached end of file\n");
break;
}
else
{
printf("Read error on input; aborting read loop\n");
break;
}
}