{magclick}
{magclick}
/*
    KAB-studio.h
        　ＫＡＢ−ｓｔｕｄｉｏで先週更新した内容
        が格納されたヘッダーファイルです（笑）。

    (C)KAB-studio 1999 - 2000 ALL RIGHTS RESERVED.
        http://www.kab-studio.com/
        info@kab-studio.com

    送信日： 2000/10/09(Mon) No.077
    配信数： 3840（ Mag2 + Pubzine ）
＊    発行元： まぐまぐ( URL: http://www.mag2.com/  ID: 0000012198 )
＊    発行元： Pubzine( URL: http://www.pubzine.com/  ID: 590 )
*/
{magclick}

/*              ２０００年１０月９日（月）の更新                  */
http://www.kab-studio.com/

・「 STL & iostream 入門」 Codian 版スタート！！
　メールマガジン STL & iostream 入門が Codian に登場！　まずは、 
STL は #05 まで、 iostream は #04 までを掲載。新たに図を追加し、 
C++ 編を本文中に埋め込みました。 STL と iostream に興味のあるあなた
はぜひ読むベシ！

[Codian]
http://www.kab-studio.com/Programing/Codian/


/*                        チョー普通な日記                        */
http://www.kab-studio.com/nikki2/

2000/10/01 (Sun)
　歯医者は人柄で選べ！！　とゆー話。そしてバイオＣ１。

2000/10/02 (Mon)
　国際システムの内定式に行って参りました！！　就職前研修結構大変そう
ですよ？？　銀ダコ美味しいですよ？？　NULL ポインタですよ？？

2000/10/03 (Tue)
　ドラクエしたりアニメ見たり。相変わらずＣＣさくらはいいねぇ。そして
謎に包まれていたゼミでの活動が今明かされる！！

2000/10/04 (Wed)
　１０月からの新番組、はじめの一歩とギア戦士電童！　どっちもなかなか
よさげじゃぁないですか。

2000/10/05 (Thu)
　タンス運んで疲れたよ〜。そして重要事項。少林拳と少林寺拳法は別物な
んだーっ！！　はぁはぁ。

2000/10/06 (Fri)
　再びタンス運び。そのわりには体重が増えつつある……。ワールドＰＣエ
キスポのパスが到着。今年は映像付きよ〜。そして、ヤクザさんは怖いです
か？

2000/10/07 (Sat)
　あああああー、ダイエーが優勝してしまった……。そしてアニメ新番組が
目白押し。結構どれもいい？


/*                         鏑矢の憂鬱                             */
http://www.kab-studio.com/Programing/KabuU/

2000/10/01 (Sun)
お便り
VC でのスタックサイズの設定方法は？
/STACK オプション
【プロジェクト】−【設定】ダイアログ
【リンク】−【アウトプット】ページの【スタック アロケーション】
DLL と別に設定したらどうなる？

2000/10/02 (Mon)
お便り
fgets() でバッファオーバーフローをチェックできる
ファイル操作をしなくて済む
「 scanf() と同じくエラーチェックができない」？
最新コンパイラ用 NULL
サンプルコード
整数値には変換できない、ポインタとしてのみ機能する 0 を作れる
使えるコンパイラが制限される

2000/10/03 (Tue)
お便り
SetWindowText() が WM_SETTEXT メッセージを送信するのか
このメッセージは SendMessage() で処理されるのか
MSDN によるとそうらしい
お便り
fgets() と sscanf()
型が望むものかチェックしてから sscanf() できる
scanf() 系のエラーチェックを信用しない方がいい
やっぱり std::fstream の方がいい

2000/10/04 (Wed)
STL & iostream 入門の再放送スタート
来週月曜には Codian に

2000/10/05 (Thu)
scanf() 系の問題を理解
サンプルコード
sscanf( "%d") はオーバーフローチェックをしない
このチェックを事前にする必要がある
やっぱり iostream の方が楽
お便り
フレームウィンドウ全体の再描画の方法は？
方法判らず
最小化しても問題ない
ウィンドウを１ドット縮小してもよさそう
サンプルコード

2000/10/06 (Fri)
お便り
デバッグ終了時に出る "Detected memory leaks!" の活用方法は？
VC のデバッグ版 new でメモリ確保して、 delete しなかった時に出る
ファイル名と行番号の情報が重要
インデックスナンバーやアドレス等も表示されるけど
とにかく new される場所を調べて delete されるようにする
ファイル名が表示されない場合
new のあとに _CrtMemDumpAllObjectsSince() を呼ぶ

2000/10/07 (Sat)
お休み


/*             プログラミング辞書・今週の追加単語                 */
http://www.kab-studio.com/Programing/Dictionary/

・追加単語：
キャッシュ ファイル列挙 プレースホルダー バウンダリ

・今週の状況：
　今回はたった４単語！　つっても、このくらいがいいような気も（爆）。


{magclick}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[KCM]
「とうとう Codian 化スタート！！
『でもメルマガと同じじゃない』
「いやいや、メールとホームページは違うメディアだよ」
『まーどっちが楽かって言えば、ホームページ見る方が楽よね』
http://www.kab-studio.com/Programing/STLiostream/
_______________________________________________________________[KCM]
{magclick}


/*                       #pragma twice                            */
http://www.kab-studio.com/Programing/PragmaTwice/

　Version 5.12
ランタイムは面倒！

「じゃ、前回の続き！」

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

『ここが実際に読み取ってるとこよね。 std::ifstream だと >> ってして
るとこ』
「それに当たるのが、ランタイムの fgets() と sscanf() 」
『ふたつ必要なんだねー。まず、最初の feof() って、やっぱ End Of File 
かどうか調べるの？』
「そう、 std::ifstream のときと同じく、ファイルの最後かどうか調べる
ランタイム関数。ここで pstFile 渡してることに注意」
『ファイルポインタね。これを渡せば、 fopen() したときのファイルを操
作できるってことね』
「そういうこと。で、中カッコの中、最初の chOneLine はとりあえず１行
ファイルの中の文字列を取っておくための文字配列」
『例によって 256 文字までなのは適当？』
「そう、こうしちゃうとファイルの１行が 256 文字以上だと入り切らない
から、ちゃんとしたプログラムじゃ使っちゃダメ」
『はいはい。次の fgets() はランタイムだって言ってたよね』
「 fgets() は、ファイルから１行読み込んで文字配列に格納するランタイ
ム関数」
『第１引数がその文字配列で今作った chOneLine 、第３引数は読み込むファ
イルを指すファイルポインタ。第２引数は？　 256 文字と関係ありそう』
「そう、第２引数は〈取り込む文字数の上限〉。文字配列が 256 文字まで
だから、入りきるように 255 文字ってしときます」
『なんで１文字少ないの？』
「……気分」
『なんじゃそりゃ』
「どうもきっちりすると不安でね。 [] で指定するのは要素数−１、ってい
うのと関係してるかも」
『０から始まるもんね。でもなんか適当』
「適当って言えば、 256 とか 255 とかの直打ちはホントはダメ」
『 const int だよね。でも実際には、やっぱ動的に変数作る、ってので入
りきるようにするのが一番？』
「そだね、ファイルサイズを知る方法があるから、それのサイズ分だけ作っ
てまずファイルを全部格納してから、って方法になるかな」
『だったらそれ教えてくれればいいのに』
「難しいよ〜？」
『う”』
「さて、 fgets() で１行読み込んだら、次は sscanf() の出番」
『あ、なんか TRACE() ちっく！』
「 sscanf() はランタイム関数のひとつで、文字列から整数とかを取り出す
もの。どう取り出すかは第２引数で、 sprintf() や TRACE() と同じ書式で
指定します」
『第１引数はその文字列だよね。なんか sprintf() の逆って感じ。第２引
数が "%d" だから整数値取り出すんだね。あれ？　第３引数の &iTemp っ
て？』
「その整数値を受け取るための変数。 Ver 4.14 ( No.064 ) を読み返して」
『なるほど、 iTemp のアドレス渡して、そのポインタ使って iTemp に値を
入れてくれてるわけだ』
「うまくいけば iTemp に 100 とか 200 とかが入ることになります」
『うまくいかなかったら？』
「戻り値に０が返ってきます。それを iError に格納して次の if でチェッ
クしてます」
『 std::ifstream::fail() の代わりね』
「ただ、 sscanf() は型のチェックしかしてくれないから。 100 の代わり
に A とかだと」
『整数値じゃないですって出る』
「 代わりに 10000000000 だと」
『整数値じゃないですって……出ない！！　エラーになんないんだ、しかも
変な値が出てるし』
「というわけで、実際には sscanf() の前にこのサイズチェックをしないと
ダメ」
『いろいろ知ってるからツッコミ入れないけど……』
「ちなみに std::ifstream では、このチェックはちゃんと行われてます」
『そゆとこも便利なのね』
「そのあとの３行は std::ifstream の時と同じ」
『 sprintf() で文字列に変えて、 CListBox::AddString() でリストボック
スに追加。って、やっぱ無駄骨って感じが……』
「ランタイムに isdigit() っていう〈文字が数字かどうか〉を調べる関数
があるから、それ使ってもいいかもね」
『ランタイムって結構色々あるのね』
「んで中カッコの最後まで行ったら再び while の最初へ。 いきなり
std::ifstream の時の話に戻るけど、 >> を使うと〈ファイルを指し示す針〉
が先に進むって言ったよね」
『うん言った。これが最後まで行ったら EOF が出てくるんだよね』
「この辺の仕組みは、ウィンドウズのファイル操作そのものの仕組みだと
思って。ウィンドウズの中に〈ファイルを指し示す針〉があって、それが
ファイルを読み取るごとに進む、って形」
『それってこの前の fopen() とかで〈ファイルを開く〉とかのと同じシス
テム？』
「そう、同じ。そういうのがウィンドウズのシステムに備わってるってこと
だね。つまり！」
『つまり？』
「 iostream とランタイム、内部的には両方とも同じことをしてるってこと」
『はー、一方は std::ifstream を使って、もう一方は fopen() とかの関数
を使ってるけど、中身的には同じことしてるんだ』
「だから、操作方法が違うってだけで、実際にやってることは同じってこと
を憶えておいて」
『ま、その方が憶えやすいけどね』
「で、今使ったランタイムのうち、 fgets() の方が読み取る度に〈次に読
み取る位置〉をひとつ進めるから」
『 fgets() 呼んでその〈次に読み取る位置〉が進んで、 feof() を呼んで
最後かどうか調べて、最後なら while から抜けるって寸法ね』
「ちなみに、この〈次に読み取る位置〉のこともファイルポインタって呼ぶ
んだよね」
『げ、それって混乱する！』
「基本的に別物だから注意してね。僕は、これからは〈読み取りポインタ〉
って呼ぶから」
『それよし！　でもポインタってことは』
「あー、いわゆるポインタとはちょっと違う……ってことでもないし……」
『煮え切らないわねー』
「ま、ファイルのどっかを指し示すポインタで、 fgets() とかしたら次に
'\n' が出るまでポインタが進む、くらいのイメージでいいかな」
『そういう機能としてポインタみたいなもの、ってことね』
「あと、読み取りポインタが進むのは fgets() だけ。 sscanf() は進まな
いから」
『どゆこと？』
「たとえば文字配列に 100 200 って入ってるときに、 std::ifstream と
>> を使うと、 100 の次に 200 って出てきます」
『うん、それが普通そう』
「ところが、 sscanf() の場合には 100 の次に 100 、つまりあくまで先頭
からしか読み込まないから」
『うわ、使えなさそう』
「ま、 sscanf() は文字列から読み取るのだからっていうのもあるんだけど
ね。だから、読み取りポインタを進めるのは fgets() の方だけ、ってこと」
『はーい』
「とういうわけで、もう一度全体を見ると」

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;

// 以下略。

『やっぱ iostream 使うよりはずっと面倒だよね』
「 fgets() と sscanf() のふたつを呼んでるし、その分とりあえず置いて
おくための変数も作ってるし」
『あと fclose() 呼んでるのもめんどいかな。こういうのもやっぱ、 C++ 
の機能を使ってるからなの？』
「そういうことになるね。でも fgets() とかのはちょっと違うかな。この
辺は中身の違いかも」
『ま、 iostream 使う方が楽そうってのは確かね』
「でもそうとも限らないけどね。使いこなすとしたら、その C++ の機能を
知らないと」
『……やっぱ、あたしもそれ知らないとダメ？』
「もちろん。近々教えるよー」
『げげ』
「最後に、今回のファイル操作は、これがすべてってわけじゃないから」
『さっき〈全部最初に読み込む〉とかって方法言ってたよね』
「ループ部分だけ見ると、こんなプログラム」

    // ファイルから読み込みます。
    char chOut[256];
    int iOneCharTemp;
    for( int iIndex = 0; iIndex < 256; iIndex++ )
    {
        iOneCharTemp = fgetc( pstFile );
        if( feof( pstFile ) )
        {
            break;
        }
        chOut[iIndex] = static_cast< char >( iOneCharTemp );
    }
    chOut[iIndex] = '\0';

『む、 for になってる。 feof() は知ってるけど、 fgetc() とか初見』
「 fgetc() はファイルから１文字ずつ読み込むためのランタイム。 MSDN 
の【ストリーム入出力ルーチン】ってページにいっぱい関数があるでしょ」
『うおいっぱいある。あ、 fopen() とかそーゆーのがあるね』
「ここにあるのは、ランタイムの中でもファイル操作をするための関数群。
こういうの使いこなせるようになるだけでも結構色々できるようになるから
ね」

/*
    Preview Next Story!
*/
『ってことは、来週はその色々？』
「ぶっぶー。そんな暇はないのです」
『自分のせいで遅れまくってるくせに』
「う”」
『というわけで次回』
＜ Version 5.13  MFC でファイル操作！ ＞
「につづく！」
『げ、水希ちゃんお得意のパターンだ！』
「いろんなライブラリを知れば、おのずと見えてくるのです！」
『ヤバイ宗教みたい……』


/*                       金菜さんの憂鬱                           */
http://www.kab-studio.com/Programing/KanaU/

const メンバ関数
#09 const メンバ関数のオーバーライド

　const メンバ関数と非 const メンバ関数は、別々に作成することができ
ます。 const のあるなしでオーバーロードができるってことは #06 で言っ
たよね。
　ここで問題になるのが、これらの仮想関数化。 const メンバ関数を 
virtual 指定すれば、派生先でオーバーライドするときも同じく const メ
ンバ関数になります。ってことは、基底クラスで const 化すると、派生ク
ラスでオーバーライドしたときに、実装部でメンバ変数を書き換えられなく
なるんです。
　具体的にはこんな感じ。

class CBase
{
protected:
    virtual void VirtualFunc() const = 0;
};

　と、 const メンバ関数を仮想化します。すると

class CSub
    : CBase
{
    int m_i;
public:
    virtual void VirtualFunc() const
    {
        m_i = 0;    // コンパイルエラー。
    }
};

　と、オーバーライドするメンバ関数も const にしなきゃいけないから、
メンバ変数を書き換える実装はできなくなるんです。
　これはかなり大問題。基底クラスでのちょっとした読み違いが、そのあと
の設計に大きく響く可能性があります。来週は意味としての const につい
て。じゃね。


/*            ２０００年１０月１６日（月）の更新予定              */
http://www.kab-studio.com/

・予定なし（汗）。
　計画はあるけど今のところ未定。まったりと期待しててね。


/*                          ご注意！！                            */

・このメールを返信しないでください。
・ご意見・ご希望・ご感想は[チョー普通な日記]よりお送りください。
http://www.kab-studio.com/nikki2/
・プログラミングに関する質問は[鏑矢の憂鬱]にお送りください。
http://www.kab-studio.com/Programing/KabuU/
・購読登録を解除したいときにはこのページで行なってください。
＊http://www.mag2.com/m/0000012198.htm
＊http://www.pubzine.com/detail.asp?id=000590
・解除は自分で行なってください。
・バックナンバーはこれらのページにあります。
http://bigbeat.tegami.com/~mgsearch/frame.cgi?id=0000012198
http://www.kab-studio.com/Freeware/

/*
    KAB-studio.h
    Weekly Mail Magazine.
    Written by Kaburaya Seiden.

    (C)KAB-studio 1999 - 2000 ALL RIGHTS RESERVED.
        http://www.kab-studio.com/
        info@kab-studio.com
*/


/*                      See you next week!!                      */

