素人プログラマーの日常

効率の良いコード、美しいコードなんて書けません。

fseek関数でモヤモヤ

息子が春休み中は、ほとんどCの画面を見ていません…。なのでまだ製作初期段階です。ひとまず今回は構造体を使ってみようということで、プレーヤ5人のデータを構造体にまとめてみました。構造体のポインタやアロー演算子などの煩わしさを避けるために、例によってグローバルで宣言しています。まあこれでは構造体の勉強としては物足りない感じですが、わざわざ面倒にするってーのも変な話なのでこのまま進めます。


それと今回は、どこに何を描画するという画面の配置がなかなかイメージ出来ないので、最初にファイルの読書きから書いていくことにしました。構造体のデータとは別に、個人の計算の詳細もログとして出力しようと思い立ち、取り掛かったのですが、なんか腑に落ちない感じです。というのも、テキストファイルを開いてすぐ新しいログが見える状態(古いログは下へ押し出される)がベストなんですが、そこが少しモヤモヤします。

ファイルの書き込む位置を調整出来る fseek関数というのがあるんですが、この関数を使っても古いログより上に書き込むことは出来ません。あくまで古いログの終端以降でしか位置を変えられないのです。最初は「fseek関数さえ使えば余裕だな」なんて考えていましたが、実際に使ってみると、いくらマイナスの数値をいれても終端より前へは移動出来ませんでした。どうしてこんな仕様になっているのか考えてみると簡単なことです。仮に終端より前へ移動出来ると、上書きされて古いログが消えてしまうからです。データがどうやって存在しているかということまで考えると、「上書き」にせずに「挿入」するのは手のかかることですから。挿入は今までそこに存在していたデータを後ろへずらしていかなくてはなりません。その際の領域確保なども上書きより面倒なことになりそうです。だから安全面なども考慮して、終端より前へは行かないようになっているのでしょう。


では、どうやって挿入するか?


一度古いログをバッファにコピーして、先に新しいログを書き込んでからコピーした古いログを書き込む。これです。でもこれ、私はやりたくありません。ログが大量になってくると、かなり重くなってきますからね。大量の文字が書き込んであるワードやテキストファイルで、上のほうに文字を追加すると重くなりますが、これは上記のように、追加した場所より下の文字を一旦どこかにコピーしているからです。容量が増えれば増えるほど、この処理は重くなっていきます。

ファイルの前にも領域確保してくれると断然処理は軽くなりますが、そうするとファイル自体のアドレスやハンドルにも影響が出てくるし、領域が確保出来ないとなるとファイルを分断する処理も出てくるので、ファイルの先頭は固定されたままなんでしょうね。どのくらいの容量から前に追加するかも判断が必要ですし…。


ってことで、挿入は諦めました。
モヤモヤしています(笑)