Engineer's Notebook

コンピュータ関係のTipsやお役立ち情報などをエンジニアが綴ります

ftell()/fgetpos()を使うならバイナリモードで!テキストモードでftell()/fgetpos()を使ってはまった件

投稿日:2018-04-29 更新日:

ftell()の不可解な動作にはまってしまいました。また同じ間違いを繰り返さないようにメモ。

『ファイルを読み込みながらftell()で読み込んだ位置を保存、fseek()でそこに戻る』

なんていうテキスト処理をVisual Studio Express 2015で作ってたんですが、なぜかftell()した位置に戻れない。

どうやら、読み込むファイルによってはftell()で返ってくる値がおかしなことになるようです。

 

スポンサーリンク

テストコード

現象再現用のテストコード作ってみました。コンパイル環境はVisual Studio Express 2015です。

読み込むテキストファイルはこんな感じ。

test1.txt

test2.txt

両方とも同じ内容に見えますよね。1行目は全く同じですが、2行目がちょっと違います。

test1.txtは1行目も2行目も改行コードは\r\n(いやゆるWindows改行コード)です。
test2.txtは1行目は\r\nで、2行目は\n(いわゆるLinux改行コード)です。

それぞれをバイナリエディタで表示したのがこちら。

テストコードは1行目を読み込んだ時点のftell()結果を表示するものです。

test1.txtもtest2.txtも1行目は同じなので、同じ値になってほしいところですが実行結果はこうなりました。

test2.txtをテキストモードで開いたときだけ値が違ってますね。

いや、2行目を読み込んだ後なら違いが出てるもの分かるんですよ。でも、1行目はtest1.txtもtest2.txtも同じなんです。なんでこんな結果になるんだろう?

 

スポンサーリンク

ftell(),fgetpos()を使うならバイナリモードで!

どうやら、改行コードが\r\nと\nが混在しているファイルをテキストモードで開いてftell()するとおかしくなるみたいです。

バイナリモードで開けば読み込むファイルの内容にかかわらず正常な値が得られるようですね。

ということで、ftell()/fgetpos()はバイナリモードで使うのがよさそうです。

原因はよく分かりません。Visual Studio Express 2015のライブラリソースを読めばわかるんでしょうけど、めんどくさいのでそういうものだと割り切ります。興味ある方はソースを読んでみてください。

 

アドセンス 336x280

アドセンス 336x280

関連コンテンツ

いまあなたにおすすめ

技術者募集

-ソフトウェア開発

Copyright© Engineer's Notebook , 2018 All Rights Reserved Powered by AFFINGER5.