こんにちは､ そしてお帰りなさい｡
今回の講義では､ 前回の課題である「ファイルの内容を逆順に印刷する」というデモを紹介します｡
そこで､ ftelメソッドとfseekメソッドを理解する必要が出てくるわけです｡
コードブロックを表示させ､ 新しいプロジェクトを作成しましょう｡
そして､ このプロジェクトはコンソール・アプリケーションになる予定です｡
ここでは､ ファイルの内容を逆に印刷する､
という名前にしておきます｡
そして､ まず最初に空のデータを含むファイルを作成することにします｡
そこで､
私のコードブロック・プロジェクトがあるダウンロード・ディレクトリに戻ることにします｡
そして､ 先ほど作成したprint
file contentsという名前のプロジェクトに移動してみます｡
だから､ ここにあるんです｡ 新しいファイル､ テキストファイルを作成するところです｡
新規テキスト文書とします｡ テストと名付けます｡ テキストを表示します｡
そして､ この中では､ 普通に「こんにちは､
ジェイソンです｡
そして､ これは何をするかというと､ 保存して､ 最後にプリントアウトを開始するんです｡
だから､ enifスペースgniodなどを先頭になるまで出力するはずです｡
コードブロックに戻り､ 標準のIOを含める必要があります｡
なぜなら､ 標準のIOにはすべての関数が含まれているからです｡
定数を作るのですが､
今回はdefineです｡
そして､ これはファイル名､ テストと呼ばれることになります｡ テキストを表示します｡
まず､ ファイル・ポインタを作成する必要があります｡ 全角のFILE
star fpで､ これをNULLに設定して初期化します｡
ループのカウンタと､ ftellから返される実際のバイト数を表示するカウンタも作成します｡
だから､ カウントがゼロに等しいと言って､ ループ制御変数をIイコールゼロにするつもりです｡
普段通りにやる｡ ファイルを開きたいのですが｡ fpイコールfopenと言うことで､
ファイル名を渡します｡ リードオンリーで通すからRだけでいい｡
これがNULLでないことを確認する｡ だから､ もしfpがnullに等しいなら､ 負の1を返すだけだと言うつもりだ｡
そうでない場合は､ ファイルの最後までシークすることにしています｡
そこで､ fseekを行いたいと思います｡
ここでは､ fseek関数を呼び出すことにします｡
これで､ 指差す位置が変わるんです｡ ファイルポインタを渡します｡
第2パラメータにゼロを渡す｡
3つ目のパラメータは､ 最後までシークと言うことです｡
だから､ その定数シークエンドを使うことにしています｡
そして､ ファイルポインタをfpの末尾､ つまりtestに設定することになります｡
テキストを表示します｡
最後まで行ったら､ 実際のカウンターをftellが指しているものに設定したいのです｡
だから､ 元の場所に戻りたいんです｡
そこで､ ここではファイルポインタの位置を取得することにします｡
そして､ fseekは実際に位置を変更したので､
ファイルポインタをファイルの末尾に移動させます｡
だから､ 先に動かしてからポジションを取るんです｡ ftellを使って位置を取得することができますね｡
ftellの場合は､ 位置を返すので､ それをcountに格納して､ f count
equals f tellと言って､ ファイルポインタを渡すことにしています｡
位置が決まったら､ ループの制御変数であるカウンターの位置から最後まで行くというwhileループを書けばいいんです｡
だからここで私は､ 私は基本的に終わりから始まりにすべてで読みたいので､
カウント未満である間と言うことができます｡
そして､ この中で､ 私のI変数の増分を言いたいのです｡
そして､ 求めたいのは､ 移動先を変えたい｡ だから､ fseekと言いたいし､
fpを指し示したい｡
背中から始まり､ シークエンドと言いたいので､
マイナスのIを指したい｡
だから､ ネガティブIは端から何バイトもすることになる｡
そこでまず最後まで移動することができたので､
それぞれの文字で読み始められるように位置を変えたいと思います｡
実際に最後までシークしたら､ あとは文字を読んでプリントアウトするだけです｡
つまり､
ここではパーセントcと言い､ fgetcとファイルポインタを言えばいいわけです｡
もう一度言いますが､ 22行目か19行目で､ まずポインタを末尾に移動させます｡
それから､ カウンタを取得しています｡ これは､ ftellを使って各バイトを読み込むのに必要な時間を教えてくれるからです｡
そして､ whileループは0からずっと､ 何バイト読み込むかカウントしていきます｡
26行目で､ カウンターをインクリメントしています｡
そして､ 末尾からIを引いたso many
byteを求めます｡ そして28行目､ その文字で読み込んでプリントアウトするんです｡
そして､ それがこのプログラムの主なロジックです｡
あとは､ 見やすくするために､ 最後に改行を入れて印刷したいだけです｡
ファイルポインタを閉じたいのですが｡
だから､ fpと言いたいし､ それからただ返したいし､ おそらくfpをnullに等しく設定したいんだ｡
では､ これをコンパイルしてみましょう｡ うまくいけば､
ファイルが逆順にプリントされるのがわかるでしょう｡
ファイルの中身を変更するのではなく､ ポジション関数を使ってファイルの最後から最初までを読み込んでいるだけなのです｡
ですから､ これを実行すると､ 反対または逆の順序で表示されるはずです｡
そして､ ここでお気づきの点は､ 逆の順序で表示されていることです｡
そこで､ まず最後のファイルをプリントアウトします｡
そして､ そのファイルをダウンロード・ディレクトリに表示すると､
出力としてプリントアウトされていることに気づくでしょう｡
enifスペースgniodなどをプリントアウトしている｡
最後にプリントアウトされるのは､ hi my name is Jasonの逆バージョンです｡
つまり､ ファイルポインタを利用して､
最後から始めて､ 最初に行き､ 逆順に内容をプリントアウトするという､
すてきなプログラムなのです｡
fseekの使い方､ ftellの使い方に注目してください｡
Fseekはファイルポインタを移動させ､ ftellは実際にファイルの場所を取得します｡
これで､ カウントを使って逆行できるようになったわけです｡
そしてまた､ マイナスIで最後から何バイトと言い､ ファイルポインタでfgetcする｡
このソースコードをソリューションとして提供しますので､ それを比較して見て､
さらに詳しく分析してください｡ お役に立てれば幸いです｡ ありがとうございます｡