#pragma twice

KAB-studio > プログラミング > #pragma twice > 075 Version 5.10 ifstream をもっと使う!

#pragma twice 075 Version 5.10 ifstream をもっと使う!

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

 Version 5.10
ifstream をもっと使う!

この前は、ファイルからデータを読み取る方法を簡単に見てみました
 ifstream ってゆーの使ったんだよね
そう、こんな感じ

void CFileTestDlg::OnBtnShow() 
{
    int i;
    std::ifstream cIFStrm;
    cIFStrm.open( "Data.txt" );
    cIFStrm
        >> i;

    char chDest[256];
    sprintf( chDest, "%d", i );
    m_cDataLstBox.AddString( chDest );
}

この関数には色々問題があるから、その辺を改良していきます
ん? ぱっと見問題なさそうだけど
まず Data.txt がなかったときの問題
え〜? あたしが Data.txt 作ったんだからないわけないでしょ
今回はね。でも、このアプリは〈ファイルを指定して読み込む〉機能も着
けるから。ダイアログに【参照】ボタン着けたでしょ
そういえば。つまり開いたファイルがあるかどうかチェックしなきゃいけ
ないわけね
そこで、 std::ifstream::fail() というメンバ関数を使用します
あ、ちょっと待って、 クラス名とメンバ関数の間の :: って、名前空間
の?
うーん、微妙なとこだね。基本的には違うけど、使い方は似てるかな。
ま、クラス名が苗字、メンバ関数が名前って考えると似てるでしょ
まーねー
同じ名前のメンバ関数が違うクラスにあったりするから、こういうふうに
フルネームで書くのがいいかな。さっきの CFileTestDlg::OnBtnShow() み
たいに、定義部はこういうふうに書くし
 ifstream::fail() でただひとつのメンバ関数を示せるってことね。じゃ
あ std:: は? これも付けた方がいい?
人に寄りけり。 ifstream は有名だから、付けなくても標準 C++ ライブ
ラリのだってことは分かるんだけどね
水希ちゃんが付けてる理由は?
クセかも
クセ、ねぇ……
ま、ぱっと見でこっちの方が分かりやすいと思うんだけどね。っと話を戻
して
 std::ifstream::fail() だよね。そいや fail って〈失敗〉とかの意味
だよね
そう、 std::ifstream::fail() を呼び出すと、ファイル名が開けていた
場合には false が、開けなかった場合には true が返ってきます
ん? 前教えてもらったのって TRUE って大文字だったけど
そうそう、 Ver 3.11 ( No.036 ) でやった TRUE と FALSE と、ほとんど
同じ。簡単に言えば、 true と false は新しいので、 TRUE と FALSE は古
いの
ふと思ったんだけど、大文字ってことは、 なんかの別名なの?
当たり! Ver 5.08 ( No.073 ) でやったね。 FALSE は0、 TRUE は
0以外を置き換えたもの
な、なにその〈0以外〉って!
 if と同じってこと
あ、そういえば、 if は0以外だと入って、0だと入らないんだよね
それに合わせているんだけど、実は TRUE の値って、決まってないんだよ

0以外、だもんね
それだと困っちゃうからできたのが、 true と false 。これは 1 と 0 
って決まってるから使いやすいわけ
でも、2種類あると混乱するなー
確かにそうかも。混ぜて使うのはちょっと不安かも。ま、自分でプログラ
ム組むときには true と false がいいかな
はーい。で、 std::ifstream::fail() ってどう使うの?
  std::ifstream::open() のあとに呼び出せばOK

    cIFStrm.open( "_Data.txt" );
    if( cIFStrm.fail() )
    {
        TRACE( "ファイルがない!\n" );
        return;
    }

確認のために _Data.txt ってファイルを開こうとしてみます
ないわけだから、 cIFStrm.fail() で……えっと、 true が返ってくるん
だから、それだと1だから if の中に入るんだよね
で、ファイルがないってことを知らせて、そのあと何もせずに関数から抜
けます
でもちょっと無味簡素よね〜
その辺はアイディア次第。実際は TRACE() じゃなくて、ダイアログを表
示したり、もう一度読み直してみたり、とか色々な方法があるから
つまり、それをどうするか、あたしが決めなきゃいけないんだ
そういうこと。ま、アプリのデザインの部分だね
なんかそーゆーのも難しそう……
ま、本来はプログラマーの仕事じゃないとは思うんだけどね。さて次。前
回 std::ifstream の >> 演算子は改造されてるって言いました
うん、ファイルからデータ取り込んで i に入れてくれるの
実は、文字配列にも入れてくれます
そういえば、ファイルに入ってるのって文字列そのものなんだから、当然
って言えば当然よね。……って、もしかしてそれって、 sprintf() 要らな
いってことなんじゃない!?
その通り!

void CFileTestDlg::OnBtnShow() 
{
    std::ifstream cIFStrm;
    cIFStrm.open( "Data.txt" );
    if( cIFStrm.fail() )
    {
        TRACE( "ファイルがない!\n" );
        return;
    }
    char chDest[256]; 
    cIFStrm
        >> chDest;
    m_cDataLstBox.AddString( chDest );
}

ってすると、  i じゃなく chDest に、文字列として書き込まれます。も
ちろん
 sprintf() 必要なし!! むっちゃ無駄骨〜
でもこれは問題もあるよ
どゆこと?
今回の目的は、ファイルから整数値を読み込んで、それをリストボックス
に表示すること。これだと、ファイルに整数値以外が入ってたら?
表示しちゃう?
そういうこと。だから、ファイルの中に入ってるデータが、整数値かどう
かチェックしないと
おー
 chDest に入れてから中に整数値が入ってるかどうか調べてもいいんだけ
ど、それより今回は、 cIFStrm の機能を使ってチェックします。なんで、
元に戻します
うお、無駄骨!
 cIFStrm >> chDest って読み取る場合には、ファイルに何が書かれてて
も読みとれるでしょ
テキストファイルの中身は、文字列そのものだもんね
 cIFStrm >> i の場合には、文字列として読み取って、それを整数値に変
換しなきゃいけない
その変換できない場合を、さっきみたいに if で拾って return すればい
いんじゃない?
そういうこと! しかも、さっきと同じ std::ifstream::fail() を使え
ばOK

    cIFStrm
        >> i;
    if( cIFStrm.fail() )
    {
        TRACE( "整数値じゃないです\n" );
        return;
    }

ホントだ、さっきのファイル開いたときと同じ
 std::ifstream::fail() はいろんなエラーチェックができるから。ちな
みに、実際にこれが機能するかどうか調べるときは、 Data.txt の最初に整
数値以外の文字列入れれば確かめられるから
〈あ〉とか入れればいーよね。ビルドして実行、うん if の中に入った
さて最後。その Data.txt に整数値3つを入れたよね。この3つ全部を読
み取る方法を見ていきましょう
あ、3回繰り返せばいいから for 使うんでしょ
ぶぶー。確かに今回は3個だけど、ファイルによって違う、ってことにす
ると?
3個って決められないんだ。ってことは、ファイルにあるの全部読み取る、
とかできればいいんだよね
そういうこと

    cIFStrm
        >> i;
    cIFStrm
        >> i;
    if( cIFStrm.fail() )    // 以下略。

ってするとどうなる?
ビルドして実行。あ、 200 って出た。ってことは、 >> を繰り返すと、
どんどん読み取ってくってこと?
そういうこと。 cIFStrm の中に〈ファイルを指し示す針〉があって、
>> を使うと、針の位置にあるデータを読み込んでから、針を次のデータの
所まで進める、っていうシステムになってるんです
便利ねー。あ、その針が、ファイルの端っことかまで行ったのが分かれば
いいんだよね
そういうこと。それを調べるメンバ関数が std::ifstream::eof() 
いーおーえふ?
 eof は End Of File の略、つまりファイルの最後ってこと
おお
ファイルの最後に来たら、このメンバ関数が true を返します。というわ
けで、これを while につかうと、こうなります

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 );
    }
}

ビルドして実行、おー、 100 200 300 全部リストボックスに出た!
この辺が、ファイル操作の基本かな

/*
    Preview Next Story!
*/
ねー、今回のって STL & iostream 入門の iostream のNo.11 と同じ?
ほとんど同じ。向こうはやや上級者向けだから解説は簡単だけどね
ってことは、こっちは初心者向け?
 if の復習とかしてたらやっぱ初心者でしょ
う”
というわけで次回
< Version 5.11 ランタイムでファイル操作! >
につづく!
火美ちゃんもちゃんと復習しないとね
分かった、ちゃんとする、復讐
字が違う!!
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。