0

したがって、100 バイトを含むバイナリ ファイルが与えられます。INVALID が原因でエラーが発生するはずだと確信していますが、そうでないのはなぜですか? INVALID に入るとセマンティック エラーが発生するのではないかと混乱しています。それとも私は何かを誤解していますか

/* VALID */  fseek(fp, sizeof(char) * 2, SEEK_SET);
/* VALID */  fseek(fp, -2 * sizeof(char), SEEK_END);
/* INVALID */fseek(fp, sizeof(char)* 2, SEEK_END);
/* INVALID */fseek(fp, -2 * sizeof(char), SEEK_SET);
/* INVALID */fseek(fp, 50, SEEK_CUR);
/* VALID */  fseek(fp, -50, SEEK_CUR);
/* INVALID */ fseek(fp, 51, SEEK_CUR);
/* INVALID */ fseek(fp, -51, SEEK_CUR);
4

2 に答える 2

2

あなたが話している「セマンティックエラー」は何ですか?

無効なファイル位置はfseek失敗の原因となり、これは の戻り値によって示されますfseek。その値を受け取って分析し、関数が成功したかどうかを判断する必要があります。上記のコードは、 の戻り値を完全に無視しますfseek

SEEK_END標準ライブラリでは、すべてのプラットフォームでポジショニングがサポートされている必要はないことに注意してください。プラットフォームは、ファイルの末尾が正確にどこにあるかを認識しない場合があります (ファイルの読み取り中に実際に突き当たるまで)。たとえば、一部のファイル システムでは、正確なファイル サイズをバイト単位で格納するのではなく、そのファイルが占有する「ブロック」または「セクタ」の数を格納します。これは、おおよそのファイル サイズとしてのみ使用できます。このため、言語仕様では、SEEK_ENDポジショニングが意味のあるサポートを保証されていないと述べています。

また、一部のプラットフォームでは、書き込み用に開かれたファイルの終わりを超えてシークすることが完全に許容される場合があることに注意してください。後続の書き込み操作は、「ギャップ」をゼロで埋めながら、新しい位置にデータを書き込みます。

于 2012-12-09T01:48:44.110 に答える
0

どのような種類の OS を使用しているかはわかりませんが (「バイナリ ファイル」と言っているという事実は、それが Windows であることを示唆しています)、Unix ベースのシステムでは、「シーク」操作は実際にはすぐには何もしません。したがって、クラッシュする可能性はほとんどありません。

以下は、W. Richard StevensによるAdvanced Programming in the Unix Env​​ironment によると、 fseekと友人が使用するコア Unix 関数であるlseek関数の説明からの抜粋です。

開いているすべてのファイルには、関連する「現在のファイル オフセット」があります。通常は、ファイルの先頭からのバイト数を測定する負でない整数です。読み取りおよび書き込み操作は通常、現在のファイル オフセットから開始され、オフセットがインクリメントされます...

lseekは、カーネル内の現在のファイル オフセットのみを記録します。I/O は発生しません。このオフセットは、次の読み取りまたは書き込み操作で使用されます。

要するに、fseekが変更するのは、構造体内の単なる整数変数である可能性が高いです。実際の I/O 操作が要求された場合にのみ、Unix カーネルはファイル システムにアクセスします。したがって、「不可能な」位置はクラッシュを引き起こしません。

于 2012-12-09T02:26:57.953 に答える