次の方法で共有


Fscanf 関数は、連続する行を想定どおりに読み取りません

この記事では、 Fscanf 関数を使用してテキスト行を読み取るときに発生する問題について説明します。

元の製品バージョン: Visual C
元の KB 番号: 60336

まとめ

ファイルがテキスト モードで開いている場合、 Fscanf 関数を使用してテキスト行を読み取ろうとすると失敗し、ファイルから 1 行のテキストのみが読み取られます。 区切り記号は [^\n]に設定されます。 Fscanf関数は最大読み取りを行いますが、区切り文字は含まれません。 そのため、ファイル ストリームは、ファイル内の最初の \n で停止します。 後続の Fscanf 関数呼び出しは失敗します。ファイル ポインターは区切り文字のままであり、 Fscanf 関数はその後に関数ポインターを進めることができません。 区切り文字の後にファイル ポインターを移動するには、次の 2 つのメソッドのいずれかを使用します。

  • 次の Fscanf 関数呼び出しを使用するようにコードを更新します。

    fscanf(stream, "%[^\n]%*c", line)
    

    %*c書式指定子は、入力ストリームから 1 文字を読み取りますが、fscanf関数呼び出しのどのパラメーターにも割り当てません。

  • Fscanf関数呼び出しの後にFgetc関数を呼び出して、ファイル ポインターを\n文字の後に移動します。

次のコード サンプルは、この問題を示しています。 コード サンプルでは、EOF に達するまでテキスト ファイルから行を読み取って印刷する必要があります。 ただし、このコード サンプルでは、ファイルから最初の行のみを読み取ります。 ファイル文字の末尾が見つからないため、ファイル ストリームに \n 文字が含まれている場合、コード サンプルは無限ループで実行されます。

コード サンプル

FILE *stream;
char line[80];

while ((fscanf(stream, "%[^\n]", line))!= EOF )
{
    printf("Line = %s \n",line);
}

次のコード例は、上記の 2 つ目の方法でこの問題を回避する方法を示しています。

FILE *stream;
char line[80];

while ((fscanf(stream, "%[^\n]", line))!= EOF)
{
    fgetc(stream); // Reads in '\n' character and moves file
    // stream past delimiting character
    printf("Line = %s \n", line);
}