5

fseekキャラクター操作を後戻りするために使用することはfscanf信頼できますか?

たとえば、fscanf10 文字を編集したばかりで、10 文字をバックトラックしたい場合はどうすればよいfseek(infile, -10, SEEK_CUR)ですか?

ほとんどの状況で機能しますが、キャラクターに問題があるようです^M。どうやらfseekそれをcharとして登録しますが、fscanf登録しません。したがって、前の例では、aを含む10文字のブロックが代わりに^M必要になります。1文字短くします。fseek(infile, -11, SEEK_CUR)fseek(infile, -10, SEEK_CUR)

これはなぜですか?

編集:fopenテキストモードで使用していました

4

5 に答える 5

8

「テキスト」ファイルと「バイナリ」ファイルの違いがわかります。ファイルがテキストモードで開かれると(fopenの2番目の引数に「b」がない)、stdioライブラリはオペレーティングシステムのテキストファイルの規則に従ってファイルの内容を解釈する場合があります(実際、必須です)。たとえば、Windowsでは、行は\ r \ nで終わり、これはstdioによって単一の\ nに変換されます。これは、Cの規則だからです。テキストファイルに書き込む場合、単一の\nは\r\nとして出力されます。

これにより、テキストファイルを処理するポータブルCプログラムを簡単に作成できます。ただし、一部の詳細は複雑になり、fseekingもその1つです。このため、C標準では、テキストファイルでfseekを定義するのは、最初、最後、現在の位置、およびftellで取得された前の位置の場合のみです。つまり、テキストファイルを探す場所を計算することはできません。または可能ですが、プラットフォーム固有のすべての詳細を自分で処理する必要があります。

または、バイナリファイルを使用して、行末変換を自分で行うこともできます。繰り返しになりますが、移植性が低下します。

あなたの場合、最後にfscancfを実行した場所に戻りたい場合は、fscanfの直前にftellを使用するのが最も簡単です。

于 2009-04-23T05:33:25.243 に答える
2

これは、fseek がバイトで動作するのに対し、fscanf はキャリッジ リターンとライン フィードが 2 バイトであることをインテリジェントに処理し、それらを 1 文字として飲み込むためです。

于 2009-04-23T04:41:54.257 に答える
1

VS2008でこれを試してみたところ、fscanfとfseekがCR文字とLF文字を同じように(単一の文字として)処理することがわかりました。

したがって、2つのファイルを使用します。

0000000:3132 3334 3554 3738 3930 3132 3334 3536 12345X7890123456

0000000:3132 3334 350d 0a37 3839 3031 3233 3435 12345..789012345

2番目の「5」に到達した15文字を読み取ってから、10文字をシークバックすると、次に読み取る文字は、最初のケースでは「X」、2番目のケースではCRLFです。

これは非常にOS/コンパイラ固有の問題のようです。

于 2009-04-23T04:48:31.417 に答える
1

Fseek はファイルの内容を理解せず、ファイルポインタを 10 文字戻すだけです。

fscanf は OS によって改行の解釈が異なる場合があります。DOS を使用していて ^M がファイルに表示されない場合、fscanf が ^M を挿入する可能性さえあります。Cコンパイラに付属のマニュアルを確認してください

于 2009-04-23T04:38:14.267 に答える
0

の戻り値をテストしましたfscanfか?いくつかのコードを投稿してください。

を見てくださいungetc。あなたはそれに対してループを実行しなければならないかもしれません。

于 2009-04-23T05:32:36.693 に答える