2017-11-13 13 views
1

私は、次のCコードのMinGW-W64(gcc version 7.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project))とwin10とVisual Studio 2017(CL.EXEバージョンMicrosoft (R) C/C++ Optimizing Compiler Version 19.11.25547)にウィンドウで `fseek(...、0、SEEK_CUR)`が失敗するのはなぜですか?

#include <stdio.h> 

int main() 
{ 
    FILE * file = fopen("ans.txt", "r+"); 
    printf("%ld", ftell(file)); // prints 0 
    fgetc(file); 
    printf("%ld", ftell(file)); // prints -18 
    printf("%d", fseek(file, 0, SEEK_CUR)); // -1 
    printf("%ld", ftell(file)); // prints 150 
    fclose(file); 
    return 0; 
} 

をテストしてみた
ans.txtファイルである(行はUNIX形式で終わります)

line 1 
line 2 
line 3 
line 4 
line 5 
line 6 
line 7 
line 8 
line 9 
line 10 
line 11 
line 12 
line 13 
line 14 
line 15 
line 16 
line 17 
line 18 
line 19 
line 20 

しかし、私はバイナリモードでファイルを開いたり、行末のスタイルを「Windows/Mac OS 9」に変更しても問題ありません。
Windowsのcrtとは何か関係ありますか?

+3

を行末。 –

+1

ファイルを正常に開いたことを確認しましたか?失敗した場合、コードはクラッシュする必要はありません。数字の後に改行(またはスペース)を印字することは賢明でしょう。 –

+0

'fgets()'の意義は何ですか?あなたのコードはそれを呼び出さない?あるいは、もっと正確には、現在私たちが見直しを要求しているコードは 'fgets()'を呼び出さない。おそらく、これはあなたが私たちに示しているものがあなたがテストしているコードと同じではないことを意味し、その違いにはトラブルの一部が含まれています。私たちは、見えないコードの何が間違っているかを推測することはできません。 –

答えて

3

これは、MSDN hereに文書化されています。テキストモード、fseek関数と_fseeki64で開かれたストリームのために

は キャリッジリターン改行翻訳がfseekを引き起こす可能性があるためと _fseeki64は、予期しない結果を生成するために、使用が制限されています。唯一のfseekと_fseeki64動作は、テキストモードで開かれたストリーム上で動作することが保証されている:起源のいずれかの値に0の相対オフセットで探し

  • _fseeki64を使用しているときにfseekor _ftelli64を使用したときに、オフセット値を持つファイルの先頭から検索します。

オープンバイナリモードでファイルを...そして、あなたは、より予測可能な結果を​​得る:あなたはWindowsのスタイルを持っていることになっているWindows上の非バイナリモードでファイルを開いた場合

FILE * file = fopen("ans.txt", "rb+"); 
+1

コードは0のオフセットでシークします –

+0

はい。 'fseek'の前に' fgetc'を呼び出すと、ストリームが壊れてしまいます。私は何が間違っているかを見るためにCRTのソースからデバッグする時間がありません。元のソースファイルがUNIXスタイルの行末であることを考えると、OPでは、テキストの代わりにバイナリとして開くことで、この翻訳内容や関連する副作用を回避できる可能性があります。 – selbie

+0

これは、Windowsのいくつかの奇妙な変わったものではありません。 Cの標準では、テキストモードで開いたファイルのfseekとftellに対する制限について説明しています。 ftellの戻り値は本質的に不透明なマジック値であり、fseekへの入力としてのみ役立ちます。 –

関連する問題