#pragma twice

KAB-studio > プログラミング > #pragma twice > 084 Version 5.19 ファイル読み込みをブラッシュアップ!

#pragma twice 084 Version 5.19 ファイル読み込みをブラッシュアップ!

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

 Version 5.19
ファイル読み込みをブラッシュアップ!

前回までで、ファイル入出力は、どんなライブラリを使ってても結局は
API を使っている、ってことが分かったと思います
うん、かなり分かった。ライブラリは謎な存在じゃないってことよね
そゆこと。では話を戻しましょう。ファイル入出力は結局は iostream を
使うのが一番楽
確かにね、なんだっけ、書式化って言うんだっけ、数字を文字列に変換し
たりとかしてくれるし、閉じるのも自動的だし
というわけで、 Ver 5.10 ( No.075 ) の最後に作ったのがこれ

void CFileTestDlg::OnBtnShow() 
{
    int i;
    std::ifstream cIFStrm;
    cIFStrm.open( "Data.txt" );
    if( cIFStrm.fail() )
    {
        TRACE( "ファイルがない!\n" );
        return;
    }

    while( !cIFStrm.eof() )
    {
        cIFStrm
            >> i;
        if( cIFStrm.fail() )
        {
            TRACE( "整数値じゃないです\n" );
            return;
        }
        char chDest[256];
        sprintf( chDest, "%d", i );
        m_cDataLstBox.AddString( chDest );
    }
}

これずっととっといたんだもんね
で、今回はこれをブラッシュアップします
ブラッシュアップって、無駄なとこ取り除いてもっと良くするんだよね。
でもそんな悪いとこある?
あるよー。とりあえず実行して、【表示】ボタンを2度押してみて
ほいほい。あら、最初のが消えてない
 CListBox::AddString() は単に追加するだけだから、前のが残ってるん
だよね
あと表示が 100 100 200 200 300 300 ってなってる
あー、ソートされてるんだね
ソート?
フォルダとかは〈名前順〉とかで並べられるでしょ。ああいうふうに並べ
ることを〈ソート〉って言います
ほほう。これってソートしない方がいいよね
そうだね、ファイルの中身そのまま表示するって仕様にしようか
……しゃれ?
リソースエディタでダイアログ開いて
無視かい。 IDD_FILETEST_DIALOG をダブルクリックっと
リストボックスのプロパティを変更して
右クリックから【プロパティ】っと
【スタイル】のページに
【ソート】があった! このチェックを外せばいいんだね
そ。……ソートがデフォルトなんだな
実行して【表示】を2回、今度は 100 200 300 100 200 300 だね
次は2重表示しないようにしましょう。どうすればいいと思う?
追加する前にリストボックスの中身、空にしちゃえばいいんじゃない?
当たり。そんじゃやってみて
げげ! えーっと、リストボックスの操作は m_cDataLstBox のメンバ関
数使えばいいんだよね、 AddString() だってそうなんだから
そうそう
じゃ、 MSDN で……
 m_cDataLstBox は CListBox クラスの変数
そうそう、 CListBox クラスメンバを表示して…… ResetContent() と見
た!
じゃあ使ってみましょう
んーと、追加する前に空にするんだから……最初で呼び出してみようかな。
m_cDataLstBox. ってやって、んでこのメンバ関数の ResetContent っと
そして?
引数はなし、戻り値なし、だから

    m_cDataLstBox.ResetContent();

って感じかな。ビルドして実行、【表示】x2、よし2重表示されない!
OK! MFC の基本的な使い方は大丈夫みたいだね
まかせてよーん
さて次。この部分をなんとかしましょう

        TRACE( "ファイルがない!\n" );

エラー処理の部分だね
 TRACE() は Visual C++ のアウトプットウィンドウに表示するだけだか
ら、これは製品じゃ使えないよね
つまり〈ファイルがありません〉って……たとえばダイアログとかで?
そうだね、やっぱりダイアログで伝えるのが一番楽かな。ダイアログを表
示するにはどうすればいい?
なんかメンバ関数使うんだよね……あ、 MessageBox() だ!
昔何度も使ったね
昔って……
とりあえずこの TRACE() を置き換えてみて
ほーい。 MSDN で……あれ、どれを選べばいいんだっけ
 OnBtnShow() は CFileTestDlg クラスのメンバ関数。 CFileTestDlg の
親クラスは?
 CDialog 、だよね。 FileTestDlg.h にそう書いてあるもん。あ、それで
CDialog は CWnd から継承してるから、 CWnd のメンバ関数は全部使えるん
だよね
そういうこと。だから CWnd::MessageBox() を使えばいいわけ
そゆことね。 MSDN のを見ると、第1引数がその文章だよね、第2引数は
キャプション、ってことはタイトルで、第3引数がアイコンだよね  
ってゆーか Ver 2.11 ( No.022 ) で使ってるんだから
そっか、それ見つつ書くと……

        MessageBox
            ( "ファイルが見つかりませんでした。"
            , "ファイルがありません"
            , MB_OK | MB_ICONEXCLAMATION );

って感じかな。ビルドして実行して【表示】ボタン! ……あれ?
ファイル名間違えさせないと
そだ。閉じて、 "Data.txt" を "_Data.txt" にして同じよーに【表示】
ボタン! うおダイアログ出た!
では次の段階。 " " で囲まれた文字列は直接プログラム上に書いちゃダ
メって言ったの憶えてる?
なんとなーく
そこで〈ストリングテーブル〉を使います。 Ver 3.16 ( No.041 ) を読
み返して
そっか、プログラムに直接書くと見つけにくいとかいろいろ問題あるんだ
ね。えーっと、ストリングテーブルはリソースの String Table ね
空欄をダブルクリックして新しく追加して
 ID とかどーすんの?
 ID は IDS_E_NOFILE=201 、キャプションはもちろん〈ファイルが見つか
りませんでした。〉
 IDS_E_NOFILE=201 って?
 IDS_E_NOFILE が ID の名前
 S は String で E は Error ね
で、リソース ID は基本的に単なる整数値。あ、これは見た方が早いか。
resource.h ってファイルを開いてみて
メニューの【開く】でっと……あ!

#define IDM_ABOUTBOX                    0x0010

この #define って定数作るときに使うのだ!
そ、 Ver 4.09 ( No.059 ) でやったね。こんなふうに、 ID は全部定数
あ、 IDS_E_NOFILE=201 って〈この ID は 201 って定数に〉って設定し
てるんだ
そゆこと。 Ver 3.14 ( No.039 ) でもやってるから見てみて
んでリソース作って、そしたら CString::LoadString() ってメンバ関数
で読み込むんだね
そういうこと。このメンバ関数に ID を渡せばいいわけだから?
こんな感じかな

        CString cStr;
        cStr.LoadString( IDS_E_NOFILE );

あう、でも cStr をどう MessageBox() に渡せばいいの?
あ、これはそのまま渡しちゃってOK

        MessageBox
            ( cStr
            , "ファイルがありません"
            , MB_OK | MB_ICONEXCLAMATION );

えええっ!?
これは近いうちにちゃんとした方がいいかもね。簡単に説明すると、
CString は LPCTSTR にはそのまま渡せるような仕組みになってるから
あ、その言い回しは〈クラスの機能〉ってヤツ?
そゆこと。 CString はクラスだからそういう便利な機能が付いてるわけ。
んじゃタイトルの方もリソースにしちゃいましょう
はーい
っと、 ID は IDS_E_NOFILE_C=1201 にして
あれ、かなりおっきな数だね
こういうふうにすると楽だからね

        const unsigned int iIDOffset = 1000;
        CString cStrCap;
        cStrCap.LoadString( IDS_E_NOFILE + iIDOffset );

んんん?
 IDS_E_NOFILE だよ、 IDS_E_NOFILE_C じゃないからね
あー! さっきの本文の方の ID なんだ、それに 1000 足すとタイトルの
になるようにするのね
エラーダイアログの本文とタイトルは一対だからね。別々に指定すると
どっかで間違えちゃうから
そーゆーテクニックって必要?
必要。趣味でのプログラムならいいけど、公開するならミスしないようで
きるだけ気を付けなきゃいけないからね
ま、確かに
じゃ、エラー処理の部分はこうなります

    if( cIFStrm.fail() )
    {
        CString cStr;
        cStr.LoadString( IDS_E_NOFILE );
        const unsigned int iIDOffset = 1000;
        CString cStrCap;
        cStrCap.LoadString( IDS_E_NOFILE + iIDOffset );
        MessageBox
            ( cStr, cStrCap
            , MB_OK | MB_ICONEXCLAMATION );
        return;
    }

うお、なんか長い!
というわけで、次回はさらにブラッシュアップします

/*
    Preview Next Story!
*/
水希ちゃんが教えるのって細々としたテクニック多いよね
僕はこれが一番大事だと思うんだけどね
一番大事?
そう、一番大事。なのに本に書いてあること少ないんだよね……
というわけで次回
< Version 5.20 ファイル読み込みをさらにブラッシュアップ! >
につづく!
細々としたことばっかだから長くなっちゃうのねー
大事なことで長くなるならよし!
うお強気!
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。