#pragma twice

KAB-studio > プログラミング > #pragma twice > 078 Version 5.13 MFC でファイル操作!

#pragma twice 078 Version 5.13 MFC でファイル操作!

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

 Version 5.13
MFC でファイル操作!

これまでに iostream とランタイムで、ファイルから読み込むプログラム
を作ってみました
で、今回は MFC を使って読み込む、と
そうです。 MFC には CFile とか CStdioFile っていうクラスがあるから、
この CStdioFile を使ってファイルを読み込んでみましょう
はーい
まず、この前のランタイムの例のように、 CFileTestDlg::OnBtnShow() 
の最初にプログラムを書いて、 return で終了させて、そのあとに iostream
のプログラムを取っておく形にします
ランタイムのプログラムはどうするの?
削除しちゃって
え〜!?
……やっぱ、テストプログラムはテストプロジェクトに書いた方がいいね
そうよそうよー。まあとりあえず、プログラム他のとこに移しとこ
その移したところに、次のようなプログラムを書き込んで

void CFileTestDlg::OnBtnShow() 
{
    // ファイルを開きます。
    CStdioFile cStdFile;
    BOOL bOpened
        = cStdFile.Open( "Data.txt", CFile::modeRead );
    if( !bOpened )
    {
        TRACE( "ファイルがない!\n" );
        return;
    }

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

    return;
// 以下、 iostream のプログラムを取っておきましょう。

どっちかってゆーと、ランタイムの時のプログラムに近いね
うん、 sscanf() を使うからその辺でね。まずは最初の部分

    // ファイルを開きます。
    CStdioFile cStdFile;
    BOOL bOpened
        = cStdFile.Open( "Data.txt", CFile::modeRead );
    if( !bOpened )
    {
        TRACE( "ファイルがない!\n" );
        return;
    }

まず CStdioFile クラスの変数 cStdFile を作ってるね。クラスだから、
iostream の cStrStrm に近い感じだよね
この辺は同じ。 CStdioFile は MFC のクラスだから MSDN に詳しく書い
てあるからね
んじゃ次の Open() 。これも std::ifstream::open() とほとんど同じだ
ね。でも微妙に違うとこも
まず MSDN で見てみようか。 CStdioFile のメンバ一覧を見て
ほい出した。……って、 Open() なんてメンバ関数ないよ? 全部で4つ
くらいしか載ってないし
かなり昔の話になるけど、 CWnd と CDialog の関係って憶えてる?
ちょっと待って思い出すから……あ、継承ってヤツ!
そう、 Ver 3.1 ( No.026 ) や Ver 3.2 ( No.027 ) でやったね。継承関
係にあるときには、子クラスは親クラスのメンバを使えるでしょ
だから CDialog は CWnd のメンバ関数も使えるんだよね。……ってこと
は、 CStdioFile にもなんかの親クラスがあって、 Open() はそのメンバ関
数なんだ!
そういうこと。その親クラスが、さっき言った CFile 。今のメンバ一覧
の下に【基本クラスのメンバ】ってあるでしょ
基本クラス?
【親クラス】のことを【基本クラス】とか【基底クラス】とかとも言うか
ら。まあ【 Base class 】の訳なんだけどね。実際は【基底】って訳される
方が多いよ
 MSDN ダメダメってことね。んじゃその基本クラス一覧! あ、 CFile 
のクラスメンバって出た! ちゃんと Open() もある!

virtual BOOL Open( LPCTSTR lpszFileName, UINT nOpenFlags,
CFileException* pError = NULL );

……なんかむっちゃ難しいんですけど
まず virtual はかなり難しいから後回し。戻り値は BOOL 、これが 
FALSE だと
ファイルなかった! だよね。 iostream は bool で MFC は BOOL
 MFC の方が古いから、 bool 型には対応してないから
第1引数は LPCTSTR 、つまり読み取り専用文字列、これがファイル名ね。
次の UINT って……?
 UINT は API でよく使われてる型のひとつで、 unsigned int のこと
略して UINT ね。〈〜のこと〉ってことは typedef されてるんだよね
そう、 API の Include\Windef.h ってファイルに書いてあるからね
あら、いつもは調べましょーってなるのに
 UINT みたいのはいっぱい引っかかっちゃうから探すの大変だからね。
API 関係の typedef はたいがいこのファイルに書いてあるから
ほー。で、この変数の意味はっと、 Flags って書いてあるからフラグに
使うんだね。あ、 fopen() の時の "r" の代わり?
そういうこと! このフラグで、読み取り専用とかを指定します
それが CFile::modeRead なんだ
 CFile::CFile() ってメンバ関数のページに書いてあるから見てみて
結構いっぱいあるねー。ところで CFile::modeRead って、名前空間?
それとも  std::ifstream::open() っての?
 std::ifstream::open() の方。 CFile がこんな感じになってるでしょ
まって、今ファイル検索で探すから
 Afx.h ってファイルにあるよ
う〜

class CFile : public CObject
{
    DECLARE_DYNAMIC(CFile)

public:
// Flag values
    enum OpenFlags {
        modeRead =          0x0000,
        modeWrite =         0x0001,
        modeReadWrite =     0x0002,
        shareCompat =       0x0000,
        shareExclusive =    0x0010,
        shareDenyWrite =    0x0020,
        shareDenyRead =     0x0030,
        shareDenyNone =     0x0040,
        modeNoInherit =     0x0080,
        modeCreate =        0x1000,
        modeNoTruncate =    0x2000,
        typeText =          0x4000,
        typeBinary =   (int)0x8000
        };
// 以下略

む、ちょっと難しそう
ぱっと見でそう考えるの悪いクセだよ〜
う”……あ、そういえば enum ってやったね
 Ver 4.09 ( No.059 ) でやったでしょ、定数を作る方法
こうすると const int みたくなるんだよね。 0x0001 とか 0x0002 とか
って整数をフラグにしてるんだよね
 0x01 と 0x02 を、ビットで表すと?
えーっと、 00000001 と 00000010 だよね。あ、ビットがずれてるのって
意味あったんだよね!
こうすれば | って演算子を使ってふたつのフラグをひとつの値に組み合
わせられるからね
 0x01 | 0x02 が 0x03 つまり 00000011 になるんだもんね。詳しくは 
Ver 4.05 ( No.055 ) を参照!
この辺も MSDN に書いてあるから。ちなみにこうやって複数のフラグを重
ねられるから Flags って複数形
ほー。……ところでー、これ見るとやっぱただのメンバ変数っぽいけど? 
だったら cStdFile.modeRead でもいけそうだけど
大丈夫だよ
ビルド、あホントだ。じゃーなんでわざわざ?
メンバ変数って、クラスの変数ごとに違うでしょ。たとえば cStdFile1
と cStdFile2 があったときに、別々のファイル名が入ってるわけでしょ
うん、入ってそう
でも enum で作られた定数値は、定数だから
どの変数でも値が同じ!! そういうのは CFile::modeRead ってした方が
いいんだ
どっちかって言うと習慣的なものかもね。あともうひとつ。 enum を使っ
てるメリットがないって気付いた?
どゆこと?
 UINT 型ってことは、どんな整数でも使えるってことでしょ
あ! そういえば、 enum しか使えないとかそういう話あったね
この UINT 型が OpenFlags 型になってれば、ここで enum されてるもの
しか使えないから安全。 UINT だとどんな値でも使えるからねー
やっぱ MFC ダメダメねー。そういえば、わざわざ unsigned な理由っ
て?
 Ver 4.06 ( No.056 ) でちょっとだけ触れたけど、ビットフラグの時は
unsigned にする事が多いかな
はじっこのビットが負のフラグになってるとなんかちょっと、ってのね
まぁ、基本的にはあんまり変わらないから、その変数が【ビットフラグに
使ってます】っていう意味にしたいときに使うくらいかな
えーっと、この第2引数関係はこれで終わり?
うん終わり。第3引数の CFileException* pError = NULL はパス
ええっ?
だって難しいから
まー難しいんならしゃーないか。あれ、でもこの部分って、さっきのプロ
グラムで書いてないよね
かなり昔教えたことだから忘れちゃったかもしんないけど、引数のあとに
= NULL とかって値を入れとくと、その引数を省略できるから
いつやった? それ
 Ver 2.11 ( No.022 ) 
うわぁ……。で、省略して書くと、その = の右側のが入れられるわけね
そういうこと。実は、 std::ifstream の時もこういうのがあったんです。
MSDN で open を検索してみて
ほい。お、いっぱいリストに出てきた……けど ifstream::open があった
このページに

void open( const char* szName, int nMode = ios::in, 
int nProt = filebuf::openprot );

あとふたつは省略できるから std::ifstream のときは使わなかったんだ。
……もしかして、この省略してるのって "r" とか CFile::modeRead と同じ
意味!?
そういうこと。 std::ifstream の便利なとこのひとつだね
は〜

/*
    Preview Next Story!
*/
なーんか今回、大復讐大会って感じね〜
だから字が違うって
もっと使い方とか色々教えてよー
それよりも、プログラムの理解力を深める方が大事だから
というわけで次回
< Version 5.14 手探りと柔軟性 >
につづく!
そーゆー地味〜な教えかたすると、人気出ないよ?
僕にとっては、火美ちゃんの成長の方が重要!!
うお!!
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。