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

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

    送信日： 2000/12/11(Mon) No.086
    配信数： 3850（ Mag2 + Pubzine ）
＊    発行元： まぐまぐ( URL: http://www.mag2.com/  ID: 0000012198 )
＊    発行元： Pubzine( URL: http://www.pubzine.com/  ID: 590 )
*/

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

・Codian に iomstream を追加
　 STL & iostream 入門から Codian に iostream を追加します！
　今回は #11 から #14 、ファイル入出力をお届けします。
[ Codian ]
http://www.kab-studio.com/Programing/Codian/
[ STL & iostream 入門 ]
http://www.kab-studio.com/Programing/STLiostream/


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

2000/12/03 (Sun)
　も少ししたら４コママンガとか載せるかもしんない。タイトルは「三人合
体ホットハーブ」……なんかダメね。

2000/12/04 (Mon)
　毎週月曜はゼミの日。でも野猿のＣＤ買ったり雑誌のバックナンバー探し
たりへんてこな特撮番組見たり。謎だ。

2000/12/05 (Tue)
　わてがすでに持ってるデジカメが新発売として発表されたとゆー謎な話。
ふっ、わては時代の先を行き過ぎてるのね。

2000/12/06 (Wed)
　武藝という雑誌とサイファイハリーのコミックス版を購入。どっちもマニ
アックやねー。かぶすた.com まだ売れ残ってます。そして vi は使いづら
いかいなか。使い方が変なのは確か（爆）。

2000/12/07 (Thu)
　最近ヒット数高いにゃー。毎日８００超えるにゃー。なぜか MFCTips01 
が高いにゃー。そして mule のない環境。

2000/12/08 (Fri)
　牡蠣フライでのんびり。ドリキャス買わないかも。買ったら時間なくなる
し。卒論書き始めました。今から書き始めないとわてはあかんので。わては
ラストスパートとか最後のど根性とか苦手なのよ。

2000/12/09 (Sat)
　メニューバー取っ払いの真実に迫る！　デザインと機能性を両立するメ
ニューバーを、今なぜ……？


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

2000/12/03 (Sun)
WTL プログラミング
リストボックスを使ってみる
AtlCtrls.h にコントロールを操作するためのクラスが入ってる
CButton  CListViewCtrl CDragListBox CMonthCalendarCtrl CIPAddressCtrl 
Attach() しなければならないっぽい
操作専用ラッパークラス
ホームページを管理するアプリを作ることが目的

2000/12/04 (Mon)
そのアプリで必要なので正規表現ライブラリを探す
gimp 内に regex.c と regex.h
STDC_HEADERS REGEX_MALLOC __STDC__ を #define してコンパイル
ちゃんと検索ができてる

2000/12/05 (Tue)
正規表現ライブラリ
regcomp() で構文解析
regexec() で文からチェック
ホームページマネージャを作ろうとしてる
フリーウェアとして公開しないかも

2000/12/06 (Wed)
WTL プログラミング
コモンダイアログクラス
CFileDialog は MFC のとちょっと違う
CFolderDialog は SHBrowseForFolder() のラッパー
CDialogImplBase から継承してないのが難点
テンプレート流オーバーライドだとメンバ変数でもオーバーできる

2000/12/07 (Thu)
新しいフリーウェア「ほめかぶ」の作成に着手
結構大変
「ウィンドウサイズを変更しようとしても高さは一定」にする機能
WM_GETMINMAXINFO に対応すればいい
GetSystemMetrics() でタイトルバーとフレーム
GetWindowRect() でツールバーとステータスバー
謎なエラー出まくり

2000/12/08 (Fri)
ほめかぶ作り
リバーの移動で RBN_HEIGHTCHANGE が通知
WTL の atlcrack.h から BEGIN_MSG_MAP_EX と NOTIFY_CODE_HANDLER_EX 
「メッセージの呼ばれる順番」が大事？

2000/12/09 (Sat)
お便り
オブジェクト指向のメッセージ送信とは？
他のオブジェクトのメソッドを呼び出すこと
状態遷移って？
内部状態が移り変わること
その図が「状態遷移図」
最近はよく使うかもしれない


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

・追加単語：
#define FORTRAN GLUT IDE MIMD 仮引数 カレントディレクトリー 
コネクションレス コミット サブセット 実引数 スーパークラス 
スーパーセット スペック 統合開発環境 ヒューマンインターフェイス 
ベンチマークテスト メモリデバイスコンテキスト ルーチン 

・今週の状況：
　今回は１９単語追加。結構粒ぞろいかなーと。しかしこう見ると、追加し
てない単語ってまだまだあるなー。引き続き単語受付中です。


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

テンプレート
#06 テンプレート引数のオーバーロード

　関数テンプレートのテンプレート引数に、デフォルトの型を指定すること
はできません。

template< class type_Default = int >    // コンパイルエラー。
type_Default NotUseDefaultPara()
{
    type_Default Ret = 0;
    return Ret;
}

　だけど、代わりに「テンプレート引数のオーバーロード」をすることがで
きます。

template< class type_Para1 >
void OverLoaded( type_Para1 p_lh, type_Para1 p_rh )
{
    printf( "1 Para\n" );
}

template< class type_Para1, class type_Para2 >
void OverLoaded( type_Para1 p_lh, type_Para2 p_rh )
{
    printf( "2 Para\n" );
}

void Use_OverLoaded()
{
    OverLoaded( 100, 100 );    // 1 Para
    OverLoaded( 100, 2.2 );    // 2 Para
}

　こんなふうに、「合うテンプレート引数」によって呼ばれる関数テンプ
レートが変わるようにすることができます。あ、でもこれは VC6 だとエラー
になっちゃうね。あまりいい例じゃないかも。次回はいい例の紹介。じゃね。


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[KCM]
『メニューバーってまだとっといてもいいんじゃないの？』
「なんで？」
『使えないときはあたしのアイコンクリックすればいいんだから』
「それがね、ブラウザによってはできないんだよね」
『げげ！　っつーか、やっぱいろんなブラウザに対応すんのって大変かも』
「ま、ここはプログラミングが中心だから、そんなに凝る必要はないけど」
『でも４コママンガ置くらしいよ？』
「そ、そうなの？　うーん、それはちょっと……」
『水希ちゃん的にはそれはダメ？』
「プログラミングのページが減ると、なんか居心地が……」
『あたしは表紙にも出てるしー、マンガにも今度出してもらおっと』
「ず、ずるい！」
　注：表紙の女の子が火美ちゃんです。
http://www.kab-studio.com/
_______________________________________________________________[KCM]


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

　Version 5.21
ファイル読み込みをさらにさらにブラッシュアップ！

「では前回の続き」

    while( !cIFStrm.eof() )
    {
        cIFStrm
            >> i;
        if( cIFStrm.fail() )
        {
            MessageError( IDS_E_NONINT );
            return;
        }
        char chDest[256];
        sprintf( chDest, "%d", i );
        m_cDataLstBox.AddString( chDest );
    }

『この chDest を while の前で宣言した方がいいってことなんだよね』
「そう。まず復習すると、 while のすぐ後にある { と } の塊を〈ネスト〉
って言います」
『で、変数はネストの中でしか使えないんだよね』
「なんでだっけ」
『えーっと、ネストの中でしか寿命がないから、外に出るとなくなっちゃう
んだよね』
「そういうこと。この〈外に出る〉っていうのがクセモノで、実は while 
のループ１回ごとにネストから外に出る形になります」
『げ、そうなの！？』
「これは、 while 自体はネストの外にある、って考えてもいいし、 Ver 2.7 
( No.018 ) でやったように、ネストを省略すると〈次の行だけループ〉に
なるから」
『なるから？』
「なるから、ネスト全体がループの繰り返しの対象、って考えてもいいかな」
『なるほど。こう見ると、ネストが１行、ってみなされるのかな』
「そういうところあるかもね。で、なんで chDest は while の前で宣言し
た方がいいんだと思う？」
『えーっと、 while でループの外に毎回出るんだから、その度に……寿命
が切れちゃう、ってことは変数がなくなっちゃう！』
「そういうこと。ループの度に chDest が削除されて再び作られて、って繰
り返しになるからね」
『その繰り返しって結構無駄？』
「場合によるけど、そんな無駄じゃない」
『あらら』
「ただ、やっぱり場合によるからね。 std::ifstream 使ったときに〈削除
されるときに呼ばれる関数〉があるって言ったでしょ」
『そっか、それが何度も何度も呼ばれることになっちゃうんだ』
「そういうこともあるから、ある程度は気を付けておいた方がいいかな。あ
と付け加えるとすると」
『付け加えるとすると？』
「 int i; の部分も while の直前に置きましょう」
『えーっと、ずっと cIFStrm 作る直前にあったんだよね。あ、そういえば
while の中に入ってからだね、 i を使うの』
「そう、だから直前に作ることにします。ファイルがないときは作らずに済
むからね」
『結構細かいね』
「ま、それよりは〈使う直前に作る〉方が分かりやすいってのもあるかな。
さて次。今度はバグを直しましょう」
『ば、バグなんてあるの！？』
「あるんだよね。データが入ってる Data.txt を開いて」
『ほい。こーなってるんだよね』

100
200
300

「最後に改行加えてから実行してみて」
『ほい。……あ、 IDS_E_NONINT のエラーが出ちゃった！！　なんでぇ！？』
「さて、なんでででょう」
『それを私に調べろと？』
「本気でプログラマーになるんなら、そういうことも調べられないとね」
『ううう……マニュアルに〈最後は改行しないで〉って書くのは』
「ダメ」
『やっぱり』
「ま、そうは言ってもこれは std::ifstream の関係だから、今の段階では
難しいよね」
『 std::ifstream の問題なんだ』
「そう、使いやすいってことで採用した std::ifstream だけど、仕組みは
難しいからこういう問題に出遭うとちょっときついかもね」
『そしたら fopen() とか使った方がいいってことになるのかな』
「それもいいし、 std::ifstream 一本で色々試していくのも悪くないだろ
うけどね。じゃ、この問題の理由について」
『うん』
「まず、 std::ifstream::eof() を呼び出した時に true が返ってくる条件
は？」
『ファイルの最後だったとき』
「そう。で、 cIFStrm >> i で整数値を読み込んだとき、最後に改行が入っ
てると、ちょうどファイルの最後に行かないわけ」
『どゆこと？』
「 cIFStrm の中に、次はどこから読み取るかが入ってるって言ったでしょ」
『 Ver 5.12 ( No.077 ) でやったね』
「最後の 300 を読み込んだとき、その位置が 300 の直後になるわけ」
『つまり、そのあとに改行が残ってるから、 std::ifstream::eof() でファ
イルの最後になんないんだ！』
「だから、改行じゃなくて 300 のあとにスペースを入れたりしても同じよ
うな結果になるから」
『スペース入れて実行、ホントだ』
「だから、改行やスペースがないときにはループは３回なんだけど、入って
るときは４回になるから」
『なければ 300 読み込んだときちょうど eof だから、４回目に入るときに
while で引っかかって終わるんだね』
「デバッグするときには、ブレークポイントを設置してこういった部分を調
べてるといいかな」
『なんか地道ね……しかもそれが分かっても解決方法分からないし』
「せかさないせかさない。重要なのは４回目のループ」
『４回目の cIFStrm >> i で読み込む時って、その改行やスペースしかない
んだもねんね、なに読み込んでるんだろぅ』
「ここで読み込めないから std::ifstream::fail() で true が返ってくる
わけ」
『そっか、これでエラー状態になっちゃうんだ！』
「でも実は、 cIFStrm >> i で読み込んだときに〈ファイルの終端が見つ
かった〉ってことで、 std::ifstream::eof() で true が返ってくる状態に
もなるんです」
『 std::ifstream::fail() かつ std::ifstream::eof() ってこと？』
「そういうこと。だから」

    int i;
    char chDest[256];
    while( !cIFStrm.eof() )
    {
        cIFStrm
            >> i;
        if( cIFStrm.fail() )
        {
            if( !cIFStrm.eof() )
            {
                MessageError( IDS_E_NONINT );
                return;
            }
        }
        sprintf( chDest, "%d", i );
        m_cDataLstBox.AddString( chDest );
    }

「ってすれば解決」
『ビルドして実行！　おーうまくいった！』
「この、 eof になってるってことに気付くかどうかなんだよね」
『気付くコツってあるの？』
「経験と試行錯誤」
『……。それと、なんか見にくくない？』
「そうだね、ネストが深くなってるし、 cIFStrm.eof() を２回呼んでるっ
ていうのはちょっと汚いかもね」
『ネスト深いのってまずいの？』
「プログラムを追うのが大変になることが多いね。この場合には」

        if( cIFStrm.fail() )
        {
            if( cIFStrm.eof() )
            {
                break;
            }
            MessageError( IDS_E_NONINT );
            return;
        }

「って書くこともできるかな」
『これはこれでなんか……あ、別に fail() の必要ないんじゃない？』
「え？」
『たとえばさー、あ、これなら while の方も要らないから……』

    while( 1 )
    {
        cIFStrm
            >> i;
        if( cIFStrm.eof() )
        {
            break;
        }

        if( cIFStrm.fail() )
        {
            MessageError( IDS_E_NONINT );
            return;
        }
        sprintf( chDest, "%d", i );
        m_cDataLstBox.AddString( chDest );
    }

『ってするとか』
「うお！　なぜこんな方法を……」
『なんか記憶の片隅に……そうそう、 Ver 2.9 ( No.020 ) で教わったよ』
「あ、そっか。確かにこれも方法のひとつ。でも……うーん」
『何迷ってんの？』
「この辺は色々人によってスタイル違うかな。 while に !cIFStrm.eof() を
残しておけば、そのループが〈ファイルの終端まで〉ってことで回ってるの
が分かるからね」
『無限ループだとどこで抜けるか分かりにくいかもね』
「ただ、そういうのにこだわると逆に解りにくくなるし、そういうのって個
人差が大きいからね」
『……で、どうしろと？』
「臨機応変で行きましょう」
『なんじゃそりゃ、それが教える立場の人間の言葉ぁ？』
「でもこれも大事なことだよ？　チーム組んで〈無限ループは使わないよう
にする〉って決めたらこういうプログラムは書かないようにする」
『まわりに合わせろってこと？』
「じゃなくてー、コーディングスタイルくらい自由に変えられるようにしま
しょうってこと。どんなコーディングスタイルでもプログラムが書ける、そ
れがプロってもんよ」
『なんかそれプログラムのスキルと違う……』

/*
    Preview Next Story!
*/
『でも確かに、掲示板とかでこういうのフレーミングしてるよね』
「僕としては、そういうのは不毛だなーと思うからね」
『確かになんでこんなことでってことで熱くなる人多いよね』
「そ、そういうのにはあんまこだわんない方がいいね」
『というわけで次回』
＜ Version 5.22 文字列クラス ＞
「につづく！」
『でもこだわらないのってなんか軟弱ぅ』
「う”」


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

・メニューバー取っ払い計画始動
　これまで目次として機能していたメニューバー（上にあるフレーム）を取
り払います。ブラウザや Java スクリプトの設定で使えない方も多いような
ので。
　このためかぶスタ内全ページを若干改装します。改装完了予定は１月中旬。
それまでの間、お見苦しい部分があるかもしれませんが御了承の程を。


/*                          ご注意！！                            */

・このメールを返信しないでください。
・ご意見・ご希望・ご感想は[チョー普通な日記]よりお送りください。
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!!                      */


