0

次のような a.txt ファイルがあります。

1 abc
2 
3 jkl

次のように、このファイルの各行をintおよび文字列として読み取りたい:

fp = fopen("a.txt", "r");
while (1) {
    int num;
    char str[10];
    int ret =fscanf(fp, "%d%s", &num, str);
    if (EOF == ret)
        break;
    else if (2 != ret)
        continue;
    // do something with num and str
}

しかし、問題があります。a.txt の行に num のみが含まれ、文字列が含まれていない場合 (2 行目のように)、上記のコードはその行でスタックします。

次の行にジャンプする方法はありますか?

4

3 に答える 3

2

次の 2 つの手順で行います。

  1. を使用して全行を読み取りfgets()ます。これは、サポートする行の長さに単純な静的制限を設定できることを前提としていますが、これは非常によくあるケースです。
  2. sscanf()行を検査して解析するために使用します。

これは、遭遇した問題を回避するものであり、通常、このような問題に対してはより適切なアプローチです。

更新: コメントに返信しようとしています。私の見方では、最も簡単な方法は、(上記のように) 常に行全体を読み取り、それから構成されていると考えられる 2 つのフィールド (数値と文字列) を解析することです。

でこれを行うと、コードで でsscanf()試したように、戻り値を使用してどのようになったかを把握できます。fscanf()

const int num_fields = sscanf(line, "%d %s", &num, str);
if( num_fields == 1 )
  ; /* we got only the number */
else if( num_fields == 2 )
  ; /* we got both the number and the string */
else
  ; /* failed to get either */

文字列が「必要」でない場合はわかりません。あるか、ないかのどちらかです。

于 2013-01-24T08:31:13.613 に答える
1

文字列の最初の文字が の場合、\r or\nこれは空の文字列になります。比較を使用できます。単語にスペース (または空行) が含まれている場合、fscanf() は適していません。その場合は、fgets() を使用することをお勧めします。

于 2013-01-24T08:15:44.427 に答える
1

「fscanfを使用して」解決する方法:

の後にint、スペースを探して (保存しないでください)、そうでないcharものを探します'\n'

int num;
char str[10];
#define ScanInt            "%d"
#define ScanSpacesDontSave "%*[ ]"
#define ScanUntilEOL       "%9[^\n]"

int ret = fscanf(fp, ScanInt ScanSpacesDontSave ScanUntilEOL, &num, str);
if (EOF == ret) break;
else if (1 == ret) HandleNum(num);
else if (2 == ret) HandleNumStr(num, str);
else HadleMissingNum();

ret何かが にスキャンされた場合は 2 になりstr、それ以外retの場合は通常 1 になります。上記のトリックは、 の'\n'後にint. したがって、コードは、両方ともすべての (先頭の) 空白を消費するの後に"%s"も使用できません。次の呼び出しは、を介した先頭の空白の消費の一部として を消費します。" ""%d" fscanf()'\n'"%d"

軽微な注意:fgets()通常は行を読み取ってからバッファを解析する方が良い方法ですが、コーディングの目標によってはそれができない場合があります。

于 2014-07-04T20:17:33.980 に答える