2
int main(void) {
    Fr = fopen("ContactList.txt", "r");
    while (fscanf(Fr, "%d", &num) != EOF) {
        ++counter;
    }

ContactList.txtは次のように類似しています:

Name Surname XXX-XXX-XXXX XXX-XXX-XXXX Adress Adress Mail
Name(1) Surname XXX-XXX-XXXX XXX-XXX-XXXX Adress Adress Mail
Name(2) Surname XXX-XXX-XXXX XXX-XXX-XXXX Adress Adress Mail
... 
4

4 に答える 4

2

fscanf"%d"入力ストリームの次の文字が数値を開始できない場合、format に0 を返します。EOFファイルの最後でのみ返される をテストするだけです。あなたは数字を解析しようとし続け、fscanf頑固に数字がないことを伝えます...確かに無限ループです。

ファイルには数字さえ含まれていません。数値を解析しようとするのはなぜですか?

于 2015-12-18T23:03:02.337 に答える
1

このfscanf()関数は、指定した書式文字列に従ってテキストをスキャンし、 format に一致しないものはすべて未使用のままにします。あなたが提示した形式では、先頭の空白をすべて消費し、その後に続くものを符号付きの 10 進整数に一致させようとします。1(1 つの) 整数との一致に成功した場合、および整数0として一致できない非空白に遭遇した場合は、戻ります。先頭の空白を消費している間EOFに到達した場合にのみ返されます。EOF

したがって、ファイルに空白と 10 進数以外のものが含まれている場合、スキャンは最終的に入力から数値を解析できないポイントに到達します (したがって、0何も消費せずに返されます) が、再試行を求め続けます。

代わりにできることは、ファイルの形式と、「行番号を数える」という意味によって異なります。あなたの言い回しとscanf()フォーマットに基づいて、最初にあなたのデータにはリテラルの行番号が含まれていると思いました (たとえば、BASIC や Fortran のソース コードに含まれている可能性があるなど)。あなたが意図したのは、単に行数を数えたいということだと思います。それがあなたが求めているものなら、次のようなことをするかもしれません:

char c;
size_t count = 1;

while (fscanf(Fr, "%*[^\n]%c", &c) == 1) {
    count += 1;
}

そのscanf()形式は、改行または EOF までのすべてをスキャンして無視し、次の文字がある場合はそれを消費します (これは改行のみです)。1改行のスキャンに成功した場合にのみ戻ります。への初期化は、改行を行ターミネータではなく行セパレータcountとして表示することに1対応するため、改行よりも 1 行多くなります。

他のアプローチもあり、上記のアプローチが完全にあなたに合わないかもしれませんが、どのように進めればよいかのアイデアが得られるはずです.

于 2015-12-18T23:02:22.767 に答える