こんにちは､ そしてお帰りなさい｡
この講義では､ ファイルの位置決めについて､ 基本的にファイルの位置を変更するためのいくつかの関数についてお話したいと思います｡
そのため､ 多くのアプリケーションでは､ シーケンシャルオーダー以外のファイル内のデータにアクセスできるようにする必要があります｡
順次とは､ 先頭から始まり､ 末尾に向かって1バイトずつ進んでいくことです｡
実際にファイルの途中まで行ってデータを取り出したり､ ファイルの最後に行ってデータを取り出したりしたい場合もありますから､
必ずしも便利とは言えません｡
全てはアプリケーション次第です｡
いつも最初から最後まで行くとは限りません｡
そこで､ ランダムな順序でデータにアクセスするために､ さまざまな関数が用意されています｡
ファイルの位置決めには2つの側面があります｡
一つはファイルの中の位置を知ること､ もう一つはファイルの中のある地点に移動することです｡
この2つは､ ファイルやファイルの位置づけについて話すときに､
実際に何を指しているのかを知るために必要なことです｡
繰り返しになりますが､ ファイル自体のどこにいるか､ ファイルのどこかに移動するかどうかです｡
だから､ ファイルを開くかどうかに関係なく､ ランダムな位置でファイルにアクセスでき､
ファイルのパートナーを移動させることができます｡
ファイルを開かなくても､ 自分がどこにいるのかを確認しながら変更することができます｡
そこで､ まずは自分の居場所を知ることから始めましょう｡
ファイル1のどこにいるのかを知るために2つの機能があります｡
ftelと呼ばれるものと､ fgetpos､ fget positionと呼ばれるものがあります｡
ftellの場合､ 実際の関数定義は非常に簡単です｡
沿って戻り､ ファイルポインタを取る｡
この関数はファイルポインタを引数として受け取り､
ファイル内の文字位置を指定する長い整数値を返すので､
位置を教えてくれます｡
この場合､ 変数fposを作成して､ それが返されるファイルポインタを渡して､
ftelを呼び出すことで使用することができます｡
f position 変数は､ ファイル内の現在の位置を保持するようになり､ 以後､
この変数を使っていつでもその位置に戻ることができるようになりました｡
つまり､ fpositionを返してくれるわけです｡
こうすることで､ 今指し示している地点の位置を知ることができるのです｡
値は､ ファイルの先頭からのオフセットをバイト数で表したものである｡
つまり､ ポインターを渡すと､ ファイルの先頭から何バイト目までを基準に､
ファイル内のどの位置にいるかを教えてくれるのです｡
この例では､ fpというファイルポインタを作り､ lengthという整数を作っているわけです｡
ファイルを開くのですが､ これは読み込み専用でしょう｡
NULLでないことを確認する｡
もしそうであれば､ エラーを返します｡
それから､ fseekは気にしないでください｡
fseekは､ 実際にはファイルの末尾に移動するだけです｡
これも私たちを助けてくれる機能です｡
あくまでftelのデモに使っています｡
Fseekはファイルの終わりまで行って､
ftell fpと言えば､ 基本的にファイルの終わりまで行っていることを教えてくれます｡
つまり､ 返されるリンクはファイルの末尾にあるわけです｡
つまり､ 長さに基づいてファイルの総サイズを返します｡
そして､ 終わりは最後に読んだ時からのバイト数です｡
では､ IDEでコードブロックの内部を見てみましょう｡
ここでは､ ファイルポインタを作成するコーディングの例を示します｡
nullに設定しました､ nullでないことを確認してください｡
開くように心がけています｡
そして､ ファイルポインタを変更するためにfseekを実行します｡
Ftelは､ 私たちがどこを指しているのかを教えてくれそうです｡
つまり､ 末尾を指し､ 末尾まで任意のバイト数になるわけです｡
これを実行すると､ 24バイトが表示されることに気づくでしょう｡
つまり､ ファイルが小さいので24バイトしか入っていないため､ ファイルの末尾にいることになります｡
一般的には､ 何か書いたり読んだりした後､ あるいはどこかに移動したところでfseekでやった後にftelを使うことになるでしょう｡
しかし､ ファイルポインタでftelを呼び出せば､ あとはlenが位置を教えてくれるだけなので､
とても簡単です｡
また､ fget position または fgetpos 関数を使用することもできます｡
そして､ これは現在のファイル位置の情報を提供する2番目の関数である｡
ftelより少し複雑です｡
これは整数を返す｡
ファイルポインタを受け取り､ f位置t型も受け取ります｡
つまり､ 最初のパラメータはファイルポインタであり､ どのファイルに読み込む必要があるかがわかる｡
第2パラメータは, standardio で定義される型へのポインタである｡ h.
fポジションtタイプは､ ファイル内のすべてのポジションを記録することができます｡
そのため､ fget position関数は､ 位置決め関数fset
positionの時に使用するように設計されています｡
そこで､ fset positionを使用し､ さらにfget positionを併用するのです｡
そこで､ fget position関数は､ ファイルの現在位置とファイルの状態情報を格納し､
操作に成功した場合は0を返し､ 失敗した場合は0以外の整数値を返します｡
そこで､ s位置型の変数を作成することができます｡
そして､ ここで言うのは､ 「ここだけ」です｡
そして､ fget positionを呼び出す｡
ファイルポインタで指定し､ f位置のタイプで指定します｡
ポインタではないので､ アンパサンド､ ofのアドレスを渡さなければなりません｡
つまり､ この場合､ 現在のファイルの位置は変数helloかここにある｡
つまり､ f position t型の変数を宣言する必要があります｡ これは､
パラメータ（2番目のパラメータ）に渡すものだからです｡
位置データを格納するための関連メモリが存在しないので､ f position
t star 型のポインタを宣言することができます｡
では､ 例を見てみましょう｡ そうすれば､ もっと理解しやすくなります｡
この場合､ ファイルポインタを作成し､ f possession t型の位置を作成し､
openを呼び出し､ fget位置を呼び出しています｡
そして､ 終了位置にはファイルポインタを渡します｡
そこで､ その位置を記憶しているのです｡
自分たちのいるポジションを
そして､ f put sと言うと､ 移動先の場所にデータを書き込むことになります｡
つまり､ ここでもfは位置を取得し､ ftellは実際にどこに書き込むか､ あるいはどこから読み込むかを教えてくれるのです｡
その中間といったところでしょうか｡
最初でもなく､ 最後でもない｡
動いているんですね｡
あなたは通常､ シークで移動するか､ 何か他のものであなたの移動､ 位置を取得し､
それはあなたがどこにいるのか教えてくれます｡
つまり､ fget positionとftellが指し示す場所を正確に教えてくれるので､
どこかに移動しても読み取れるということですね｡
さて､ ここまでのファイルでの位置の設定は､ 今いる場所を読み込むだけでした｡
何かを設定しない限り､ 自分たちの置かれている状況を本当に読み取ることはできない｡
読み書きをしたのだ｡
つまり､ ftellを補完するものとして､ fseekもあるんですね｡
そしてfseekは､ 自分のポジションのためにどこかに移動することを許してくれるのです｡
intを返す｡
ファイルポインタ, long fset, integer originalを返す｡
最初のパラメータは､ 再配置するファイルへのポインタです｡
2番目と3番目のパラメーターは､ ファイルのどこに移動したいかを定義します｡
第2パラメータは､ 第3パラメータで指定された基準点からのオフセットである｡
基準点には､ あらかじめ定義された名前で指定された3つの値のいずれかを指定することができる｡
シークセット､ シークカレント､ シークエンド｡
シークセットは､ ファイルの先頭を定義する｡
シークカーはファイルの現在位置を､ シークエンドはファイルの終端を定義する｡
したがって､ テキストモードのファイルでは､ 第2引数はftelが返す値でなければならない｡
だから､ fseekとftelでは､ 一緒に使われていることに気がつくはずです｡
そのため､ テキストモードファイルの第3引数には､ シークを設定する必要があります｡
テキストファイルの場合､ fseekによるすべての操作はファイルの先頭を参照して行われます｡
バイナリファイルについては､ あまり学習していません｡
しかし､ バイナリファイルの場合､ offset引数は単に相対的なバイト数である｡
従って､ 基準点をシークカーに指定する場合､ オフセットに正または負の値を指定することができます｡
では､ 例を見てみましょう｡
この例では､ 再び､ fputsを実行します｡
そこで､ あるデータをファイルに書き込んでから､ fseekを使います｡
Fseekはあなたを感動させます｡
これは7バイト移動すると言っているのですが､ シークセットを使って､
基本的に先頭から7バイトのところに移動したいと言っているのです｡
そして､ ファイルの先頭から7バイト移動させることで移動させることができるのです｡
7バイト後に､ 実際にデータを書き込むことができるようになります｡
また､ ftellを使って､ 7バイト後にどこにいるのかを確認することもできます｡
今いる場所から取り戻すために､ その情報を利用することができます｡
繰り返しになりますが､ fseekとfgetsの要点は､ どこに書き込むか､ あるいはどこに読み込むかを指定するために､
自分の位置を確認するということです｡
つまり､ fseek sは実際に位置を移動させるもので､ tellは位置を知らせるものです｡
Fsetの位置もfseekと同じです｡
しかし､ fsetの位置はもう少し複雑です｡
fsetの位置と一緒になります｡
ですから､ fset get get positionもfset positionと非常によく似ています｡
fsetの位置で､ 第1パラメータを開いているファイルへのポインタとして指定する｡
第2パラメータは､ f位置t型のポインタである｡
アドレスに格納されている位置は､ fget positionを含んで取得されたものである｡
つまり､ fsetの位置には､ ファイルポインタと､ 実際の変数があります｡
そして､ ここの変数は以前にfget positionの呼び出しによって設定されたものです｡
ここでも､ fsetとfgetを一緒に使うことになります｡
fset位置は､ エラー時に0以外の値を返し､ 成功時に0を返す｡
この関数は､ fget positionで返される値を操作するために設計されています｡
だから､ ファイルの中で前に行ったことのある番号の場所に行くのにしか使えないんです｡
Fseekでは､ 適切なオフセットを指定するだけで､ 任意の位置に移動することができます｡
ここで､ fの位置とtの位置が決まったように見えます｡
ファイルを開き､ fgetポジションを呼び出します｡
fgetの位置では､ ポインタを移動させたい場所､ つまり実際にファイルを読み書きする場所を指定しているのです｡
そして､ fputsを使って､ 移動させた場所に移動させるのです｡
そして､ fset positionは､ 書き込む場所を具体的に設定し､
そこから書き込むというものです｡
そのため､ これらの機能では､ 実際にどこを指しているのか確認したいものです｡
これは､ チャレンジしてみると､ もっとわかりやすくなると思います｡
だから､ 読書や執筆では､ 常にどこかに向かって書き進めたいものなのです｡
いつも始まりや終わりのために書きたいわけではないのです｡
それで､ これらの関数は､ ファイルの中の任意の場所に位置を移動するのに非常に便利です｡
ありがとうございました｡