#pragma twice

KAB-studio > プログラミング > #pragma twice > 076 Version 5.11 ランタイムでファイル操作!

#pragma twice 076 Version 5.11 ランタイムでファイル操作!

前のページへ 表紙・目次へ 次のページへ

 Version 5.11
ランタイムでファイル操作!

前回は iostream を使ってファイル操作をしました
 std::ifstream ってゆーの使ったんだよね
今回はCランタイムの関数を使って、ファイル操作をしようと思います
ランタイムにもそういう機能があるんだ
まずはいつもの CFileTestDlg::OnBtnShow() の最初をこう書き換えて

void CFileTestDlg::OnBtnShow() 
{
// ここにあとで追加します。

    return;

    int i;
// あとは前回のと同じ。

ん? return したら関数終わっちゃうよ
その return の前にあとで紹介するプログラムを描き込むから
どゆこと?
これからランタイムの使い方を教えるんだけど、これはあくまで勉強用の
テストだから、あんまり CFileTestDlg::OnBtnShow() の中身は書き換えた
くないんだよね
つまり iostream 使ったのをメインにしたいんだよね
そういうこと。だから、テストは CFileTestDlg::OnBtnShow() の最初に
書き加える形にして、この前作った部分はとっておきます
 return ですぐ関数が終わっちゃうのは、 iostream 使った部分が実行さ
れないようにしてるから?
そう。ま、ホントはテスト自体はテスト用のプロジェクトでした方がいい
んだけどね
前もそんなこと言ってたね
でもそうすると Data.txt とかの用意が面倒だから、ここでしちゃうこと
にします
手抜き〜
う”
で、 return の前はどうするの?
とりあえず、 iostream を使ったときと同じことをランタイムですると、
こんな感じになります

void CFileTestDlg::OnBtnShow() 
{
    // ファイルを開きます。
    FILE *pstFile
        = fopen( "Data.txt", "r" );
    if( !pstFile )
    {
        TRACE( "ファイルがない!\n" );
        return;
    }

    int iError = 0;
    int iTemp = 0;
    while( !feof( pstFile ) )
    {
        char chOneLine[256];
        fgets( chOneLine, 255, pstFile );
        iError = sscanf( chOneLine, "%d", &iTemp );
        if( iError == 0 )
        {
            TRACE( "整数値じゃないです\n" );
            break;
        }
        char chDest[256]; 
        sprintf( chDest, "%d", iTemp );
        m_cDataLstBox.AddString( chDest );
    }

    // ファイルを閉じます。
    fclose( pstFile );
    return;

// 以下略。

うあ〜、長いし分かんないし難しそう!!
初めて出てくるのがいっぱいあるからねー。ひとつひとつ見ていくよ。ま
ずここから

    FILE *pstFile
        = fopen( "Data.txt", "r" );
    if( !pstFile )
    {
        TRACE( "ファイルがない!\n" );
        return;
    }

まず fopen() から。これはランタイムの関数のひとつで、ファイルを開
くもの
 std::ifstream::open() と同じってことだよね
そう、この関数を呼ぶことで、ファイルが使えるようになります。第1引
数は開くファイルのファイル名、第2引数はファイルモードの指定
ファイルモード?
書き込みか、とか、読み込みか、とかを指定するための。 "r" だと読み
込み専用、 "w" だと書き込み専用。この辺は fopen() のリファレンスに書
いてあるから
文字列で指定って、 TRACE() とか sprintf() とかみたい。でも、なんで
std::ifstream のときにはこういうの使わなかったの?
 std::ifstream はそういうのを省略できるから、わざわざ書かなくてよ
かったわけ
へー
この〈省略できる〉っていうのは C++ 言語の機能。ランタイムは C 言語
の時代に作られたから、そういう機能がついてないわけ
それだけ使いづらいってこと?
そうなるんだよね。これから見ていくけど、そういうのいっぱいあるか

げげ
さて、 std::ifstream はクラスだから、このクラスの変数を作って、
ファイルの情報を全部蓄えることができました
へー、そうだったんだ
ところが、 fopen() は関数だから、そういう情報を外に置かなきゃいけ
ない
もしかしてそれが pstFile って変数?
そういうこと。 FILE っていう構造体へのポインタが返ってくるから、そ
れを受け取って使います
? こうぞうたいってなに?
……クラスみたいなもの!
ホントにぃ?
基本的にはね。クラスと同じく、いろんな変数を格納できる型だから
その中にファイルの情報が入ってるんだ
注意して欲しいのは、ポインタとして返ってくること
それって変じゃない? 変数って関数から抜けるとなくなっちゃうんだか
ら、そういうことってできないはずでしょ
 Ver 4.13 ( No.063 ) でも見たけど、変数を自由に作れて自由に削除す
る方法があるから
あ、 new と delete とかゆーのだよね
ここで返ってくるポインタが指し示してる変数は、そういうふうに作られ
た変数ってことだね。あとでちゃんと削除するし
へー
で、この FILE のポインタを〈ファイルポインタ〉って言います。よく使
われる単語だから憶えといて
って、そのまんまじゃん
あ、でも〈ファイルポインタ〉って違う意味で使われることもあるから
ちょっと注意
はーい
で、もしファイルがなかったら、このポインタには NULL が返ってきます
ぬるってなに?
……あ、 NULL 教えてなかったか……。ポインタってアドレスを入れる変
数でしょ
そだよ、変数はメモリ上にあって、メモリの住所がアドレスで、それを取
っておくのがポインタ
で、アドレスは整数値でしょ。この整数値が0のアドレスを NULL ってい
います
??
つまり NULL == 0 って考えればOK。実はメモリ上の0の部分は使えな
いから、この 0 のポインタを使って操作することはできないから
つまりエラーのときはこの NULL ってのが返ってくるってことなんだよね
そういうこと。ポインタが戻り値として返ってくる場合には、こういうふ
うになってることが多いから。成功したら、使えるアドレス。失敗したら、
使えない NULL が返ってくる、ってこと
で、次の if( !pstFile ) はそれをチェックしてるんだ。 !pstFile だと
0のとき0以外になるから if の中に入ってエラー表示、だね
これが std::ifstream::fail() の代わりになってます
これって TRUE と FALSE にちょっと似てる感じ
うん、そういう意味合いのものだね。基本はただの整数なんだけど、それ
に別の名前を付けて意味を持たせてるって感じかな。ちなみに null は英語
でゼロとかって意味
でもなんで NULL って別名付けるの? 0 でもいーじゃん
難しいところだね。 NULL はポインタにしか使わないから、そういう意味
で分かりやすいってことはある
あ、つまり普通の整数値の 0 と、アドレスの 0 の違いみたいな?
なんだけど、実際には NULL ってまんま 0 と同じだから、見た目の違い
しかないんだよね
どゆこと?
つまり int i = NULL; ができるってこと。これがバグの原因になったり
もするから、 NULL じゃなく 0 を使う人も最近多いみたいだね
なんか複雑……
ま、この辺は C++ のことをもっと知らないとわかんないかも
やっぱ iostream の方が分かりやすいかなー
確かにファイルポインタが NULL かどうか、っていうのに比べればね。こ
こから先、ファイル操作を擦るときにはファイルポインタの pstFile を使
っていくことになります
この前の cIFStrm の変わりね
さて、ずばっと飛んで、この行を見て

    // ファイルを閉じます。
    fclose( pstFile );

あ、これがさっき言ってた、ファイルポインタを削除するってとこでしょ
そう、ファイルポインタが指し示す変数はローカル変数じゃない形で作ら
れたものだから、自動的に削除されないんだよね
だから使い終わったら削除する、と
削除したらそのファイルポインタは使えないから
また fopen() しなきゃいけないってことだよね
そういうこと。 fclose() したあと pstFile = NULL してもいいかも
その方が安全そうね
それと、ファイルポインタを削除するだけじゃなくて、実際にファイルに
アクセスできなくする機能もあるからね
どゆこと?
ちょっとあとで説明するけど、ファイル操作って基本的にはOSの機能
ウィンドウズに、ファイルを操作する機能が付いてるんだ
 fopen() はファイルを使えるようにする関数、 fclose() はもう使わな
くていいよう閉じる関数。このふたつは、間接的にウィンドウズのファイル
操作機能を呼び出してるもの
なんか MFC みたい
そういう感じのもの。で、ファイル操作をするためのデータを、動的に作っ
た変数に入れて、そのポインタを返す
それがファイルポインタなんだ!
 fclose() するときには、まずウィンドウズに〈このファイルは使いませ
んよ〉って宣言してから、動的に作った変数を削除する。なんか今の話だと
変数作って削除するってとこだけ注意が向いてるみたいだから
うん向いてた。つまり、変数を作って削除、も機能のうちだけど、ファイ
ルを開いて閉じる、っていうのの方がちゃんとした機能ってことね
そうじゃなきゃ std::ifstream::open() の意味ないでしょ
でもさ、 std::ifstream の方には fclose() に当たるのないでしょ
 std::ifstream::close() ってメンバ関数がそれに当たるの。でも、自動
的に呼ばれるから使ってないだけ
自動的に呼ばれる?
そう、これも C++ の機能のひとつで、デストラクタって機能を使ったも

これも C++ の便利さなんだ
こういうふうに C++ のいいところが使われてるから、 std::ifstream の
方が便利なんだよね。とういうわけで次回に続く!

/*
    Preview Next Story!
*/
お、 while ループは来週?
またこーやって長くなる。こういうのって普通の本にも載ってるんだよね
でもあたし、水希ちゃんの解説で聞きたい!
それってもしかして……
というわけで次回
< Version 5.12 ランタイムは面倒! >
につづく!
だって水希ちゃんの解説って……
……解説って?
タダじゃん!
あう
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。