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

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

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

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

・更新なし。
　嵐の前の静けさ？


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

2000/10/15 (Sun)
　おばあちゃんの四十九日。世の中辛いこと多いよね＜あんたの日記読んで
もそう思えん（爆）。

2000/10/16 (Mon)
　セーフモードで起動。再セットアップの危機！？　パスネット便利、そし
てゼミ第１回卒業研究中間発表。

2000/10/17 (Tue)
　ワールドＰＣエキスポに行ってまいりました！　水上バスで行く初めての
ビッグサイト、格安デジカメによるフォトレポート、今の「コンピューター」
がここに集結！

2000/10/18 (Wed)
　サンマルクでお食事。そして祝２２万ヒット。ここ最近の goo からのお
客さん増がうまく効いてます。

2000/10/19 (Thu)
　就職前研修の添削課題を送ったりドリキャス欲しかったり自分のミスに衝
撃を禁じ得なかったり。なんだかんだ言って結構色々ある人生よね。

2000/10/20 (Fri)
　イラスト描きまくり。わての将来の夢は小説家か漫画家（爆）。とか言っ
といてプログラミングもするし。 WebMoney に期待大。アルジェントソーマ
にも期待大。コレクター・ユイは最終回（泣）。かなりいい出来でした。

2000/10/21 (Sat)
　今日はテレビ関係中心。やっぱアニメって面白いなー、うんうん。


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

2000/10/15 (Sun)
お休み

2000/10/16 (Mon)
お便り
メンバ関数ポインタについて
サンプルコード
格納できるのは指定した「クラス・戻り値・引数」のメンバ関数のみ
格納するときはクラス型変数とは関係ない
使う時だけ関連づける
自由度が高いのがメリット
お便り
ActiveX について
ActiveX は範囲が広い
Visual C++ 5 パワフルテクニック大全集、でも上級者向け
ActiveX コントロールを作るのが良さそう
お便り
フレームウィンドウ全体の再描画
ModifyStyleEx() でできた

2000/10/17 (Tue)
お休み

2000/10/18 (Wed)
C マガジンの付録 BCB5.5.1 
最近は gcc for WIN32 ( Cygwin ) よりも使うこと多い
コマンドラインコンパイラを VC から使う方法
ツールバーにコマンドを登録
[アウトプットウィンドウを使用]が便利

2000/10/19 (Thu)
STL & iostream 入門でミス
#06 の iostream の解説
seekp( 0, std::ios::cur ) は進まない
サンプルコード作りに四苦八苦
各コンパイラの iostream ベンダ
お便り
VC のようなドッキングウィンドウを作るには？
手作りするしかなさそう
Codeguru にサンプルコードがあるかも

2000/10/20 (Fri)
知識量＝ Google データベースサイズ
就職前研修で調べる
生の情報が得られる
プログラミング辞書の単語がいい感じ

2000/10/21 (Sat)
#pragma twice
API を使ってファイル IO をする回
API って大変
これからの予定


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

・追加単語：
TRACE 改行文字 エスケープシーケンス スーパースカラー SIMD 
ランダムアクセス シーケンシャルアクセス リングバッファ ホスト "

・今週の状況：
　今回は１０単語追加。こっちで追加したのもいくつかあるけど。なんだか
んだ言って、単語によってはかなり調べないと納得いかないものも結構ある
んで、その点で今くらいの数がちょうどいいかもしんない。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[KCM]
『なんでも、ホームページのデザインが変わるらしーよ』
「上のメニューバーがなくなるそうだけど」
『ええっ！！　あ、あたしのボタンがなくなっちゃう……』
「 IE4 だともともと効かなかったらしいけど」
『効かなくてもいいのよっ、顔が出てれば』
「んな無茶苦茶な」
『でもなんでメニューバーをなくすの？』
「あのメニューバーが使えるブラウザってそんな多くないらしくて」
『なんだかんだ言ってもスタイルシートって安心して使えないよね』
「だから普通のメニューにした方がいいっていうのと、もうひとつ」
『もひとつ？』
「フレームだとページ構造が複雑だから、それをシンプルにっていうのも」
『確かに、やれメニューバーは表示するようにリンクしてとか』
「シンプルになればページの全体像も掴みやすいだろうから」
『うん、フレーム取るの賛成賛成！　でもあたしいなくなるのや〜』
「またわがままな……」
http://www.kab-studio.com/
_______________________________________________________________[KCM]


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


　Version 5.14
手探りと柔軟性

「ではこの前の続き。今回は実際に読み取ってる部分を見てみましょう」

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

『つっても、この前のランタイム使ったときとほとんど同じだよね』
「結局は sscanf() や sprintf() 使ってるしね。ってゆーか実際に MFC 
使ってるとこは」

cStdFile.ReadString( chOneLine, 255 )

『だけだねー。ぱっと見、 fgets() の代わり？』
「そういうこと。 CStdioFile::ReadString() は、ファイルから１行文字列
を取り込んで、第１引数にコピーします」
『 255 ってのは、１行がそれ以上だと入んないってことだよね』
「そう、それ以降はカットされます。で、重要なとこ。 CStdioFile には、
EOF を調べる方法がありません」
『げ、そなの。親クラスの CFile の方にも？』
「ありません。代わりに、 CStdioFile::ReadString() の戻り値が、最後ま
で行くと NULL が 返ってくるから」
『それを while で調べてるわけね。で、 while の中はランタイムと同じっ
と』
「あと最後に、この前のプログラム全体のを見て。 close() みたいなの呼
んでないでしょ」
『ホントだ、これって std::ifstream 使ったときと同じってこと？』
「そういうこと。クラスには〈後始末をする機能〉があるから、それを
CStdioFile も std::ifstream も使ってるわけ」
『クラスじゃない、ランタイムの方は fclose() 呼ばなきゃダメってことね』
「さてここで、もうちょっとブラッシュアップしていきましょう」
『どっか手を加えるとこある？』
「たとえば、 sscanf() して sprintf() してるとことか」
『そうよねー、整数値として取り出して、また文字列として書き込むってか
なりムダ入ってるよね』
「どんな感じにすればいいと思う？」
『こういうのわざとするのって、確か〈入ってる値が整数値かどうか〉を確
かめたかったからだよね。じゃ、その確かめるってのを直接すればいいん
じゃない？』
「そういうこと！　そのチェックのために、 isdigit() っていうランタイ
ムを使います。そうすると、冒頭のプログラムの部分はこうなります」

    char chOneLine[256];
    while( cStdFile.ReadString( chOneLine, 255 ) )
    {
        for( int iF1 = 0; iF1 <= 255; iF1++ )
        {
            if( chOneLine[iF1] == '\0' )
            {
                break;
            }
            else if( chOneLine[iF1] == '\n' )
            {
                chOneLine[iF1] = '\0';
                break;
            }
            else if( !isdigit( chOneLine[iF1] ) )
            {
                TRACE( "整数値じゃないです\n" );
                return;
            }
        }

        m_cDataLstBox.AddString( chOneLine );
    }

『おー、 sscanf() と sprintf() の部分が、ごっそり for ループに置き換
わっちゃったね』
「べたな方法だけど、文字ひとつずつチェックする仕組みにしてるから。ま
ず for 」
『 255 ってことは文字サイズのチェックだよね』
「そう、配列を超えないようにするための for 。だから、実際にはこの for
の条件でループが終了することは少ないです」
『あ、だから for の中に break とか return とかいっぱいあるのねー。 
for の iF1 は、配列のインデックスね』
「このインデックスナンバーを使って、文字配列内の文字ひとつひとつを見
ていく仕組みにしてます」
『１回のループで１文字、ね。最初の if は、終端文字かどうかチェック』
「もし終端文字なら break して for から抜けます」
『で、それを CListBox::AddString() でリストボックスに追加するわけね』
「終端文字じゃなかったら次の else if へ」
『今度は改行文字かどうかのチェック。あれ、改行文字を終端文字に置き換
えてるの？』
「そう、この置き換えの部分をコメントアウトして試してみて」
『ビルドして実行。あ、 100・ってなんかゴミが付いてる』
「改行文字が残ってるとそう表示されちゃうんだよね」
『なんで今まで表示されなかったんだろ』
「 sscanf() で整数値だけ取り出していたからね」
『あー、このときに改行文字がどっか消えちゃってたんだね』
「で、改行文字だった時にもその行の読み取りは終了だから、 break 」
『終端文字でも改行文字でもなかったら、最後の else if 。ここでやっと
isdigit() が出てくるのね』
「 isdigit() はランタイムの関数で、文字が整数値かどうかチェックしま
す」
『 MSDN にも載ってるね。整数値じゃないなら０が返ってくるから、それを
! で反転させて if でチェック、ね』
「で【整数値じゃないです】っていうエラーを表示」
『ひとつずつ見ていけば簡単ね』
「まーね。でも、何もないとこからいきなり書くと結構大変だと思うよ」
『たとえば？』
「たとえば for ループで文字数制限をしないとか、 100・って表示されて
もその原因が分かんないとか」
『う”、ありがちそうかも』
「あと、これだとかなり大きな数字まで入るから、あとで int とかに入れ
るときには」
『サイズのチェックしなきゃいけないんだ！　めんどくさー』
「こういうことに気を回すためには、実際にプログラムを書くことと、解説
を良く読むこと、その両方が大事」
『どゆこと？』
「 100・の問題なんかは、単に〈こうすればいい〉って聞くだけじゃなくて、
実際に自分で解決する練習しないとね」
『つまり試行錯誤しろってこと？』
「そういうこと。特にプログラミングっていうのは、コンピューターの中身
っていう〈見えないもの〉を相手にするから、そういう手探りに慣れてない
とね」
『失敗してもいいから、とにかくいっぱいプログラム作ってけってゆーのね』
「でもそれだけじゃダメ。自分に都合のいいことしかしないから」
『自分に都合のいいこと？』
「たとえば〈入力される数字は８桁まで！〉とか」
『確かに、他の人に使ってもらうときにはそういうことしちゃまずいよね』
「手探りで調べていくと、どうしても知識に偏りができちゃうから、それを
補うように他の知識もどんどん入れるようにして、できればその知識につい
ても調べるようにして」
『要するに手も頭も動かせってことね。なんか結構大変……』
「何をいまさら。さて！　最後に、 std::ifstream を使った時ののブラッ
シュアップについて」

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

「ってなってたけど、これはこのままでいいかな」
『い、いいの？　 sprintf() が邪魔だなー』
「そういう場合には、 sprintf() の代わりに std::strstream っていうも
のがあります」
『あ、 STL & iostream 入門でやってたのだ！』
「でもこれ使うのは結構面倒だからパス」
『ええっ！？』
「それよりかは、 isdigit() 使った方が楽かな」

    char chOneLine[256];
    while( !cIFStrm.eof() )
    {
        cIFStrm.getline( chOneLine, 255 );
        for( int iF1 = 0; iF1 <= 255; iF1++ )
        {
            if( chOneLine[iF1] == '\0' )
            {
                break;
            }
            else if( chOneLine[iF1] == '\n' )
            {
                chOneLine[iF1] = '\0';
                break;
            }
            else if( !isdigit( chOneLine[iF1] ) )
            {
                TRACE( "整数値じゃないです\n" );
                return;
            }
        }
        m_cDataLstBox.AddString( chOneLine );
    }

『 cIFStrm >> で取り出してたのが、 getline() ってメンバ関数に変わっ
てる……これって CStdioFile::ReadString() と同じよね』
「そう。実際には cIFStrm >> chOneLine ってできるんだけど、最大サイズ
の設定に std::ifstream::width() ってメンバ関数を呼ばなきゃいけないし、
こっちの方が分かりやすいかなと思って」
『そりゃ分かりやすいね、さっきのとほとんど同じだもん』
「でも、別にこっちじゃなくて、最初の sprintf() 使った方がいいと思う
けどね」
『そなの？』
「ま、この辺は好みの問題かも。重要な点はふたつ。ひとつは、内部的な仕
組みをちゃんと理解して、自由にプログラムが組めるようになること」
『内部的な仕組みって？』
「配列にどうアクセスしてるのかとか、文字がどうなってるのかとか」
『あー』
「もうひとつは、エラーチェックをちゃんとすること」
『ヘンテコな値を入れられてもちゃんと対処できるようにってことね』
「そういうこと」

/*
    Preview Next Story!
*/
『なんか今回は意識論って感じ』
「それが一番大事なんだけどね」
『そなの？』
「倫理観のない医者に診られたくないでしょ」
『というわけで次回』
＜ Version 5.15 API でファイル操作 ＞
「につづく！」
『でもさ、医学部とかでそういうこと教えてないっぽいよね』
「だから日本はダメなんだ！！」
『なんだかなー』


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

const メンバ関数
#11 抜け道

　const メンバ関数を使うと「このメンバ変数さえ使えれば！」っていう場
面が多々あります。その制約のために設計をやり直さなきゃいけなくなった
ら大変よね。
　そこで、 const メンバ関数の中でもメンバ変数を非 const にできる方法
をふたつ紹介します。
　まずひとつめは、 this ポインタをキャストする方法。これを使うと、 
#09 の問題はこう解決できます。

    virtual void VirtualFunc() const
    {
        const_cast< CSub * >( this )->m_i = 0;
    }

　このように this ポインタを const_cast を使って非 const へとキャス
トすれば、まったく問題なく使うことができます。
　もうひとつは mutable を使う方法です。 mutable は C++ のキーワード
のひとつで、メンバ変数を修飾するものです。これを付けると、メンバ変数
が const メンバ変数の中でも書き換えられるようになります。

    mutable int m_i;

　これも #09 での解決方法です。こうすることで、 const メンバ関数の中
でも m_i は書き換えられるようになります。
　言わずもがなだけど、どっちもできるだけ使っちゃダメ。ホントは絶対使
わないくらいがいいんだけどね。一度使い始めるとキリがなくなっちゃうし。
　ただ、少しくらいなら使ってもいいかな、って思うの。前回の「意味的に
は const のはず」って場合とかね。でもホント、できるだけ使わないのが
一番なんだけどね。来週はトレードオフについて。じゃね。


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

・Codian - iostreamに追加！
　Codian の iostream にページを追加します！
　今回は「 STL & iostream 入門」の中から iostream の #05 と #06 を追
加。  std::strstream でのポインタ操作についてです。しかも図入り、そ
のうえメルマガでは間違っていた部分も改変しています。
　
・KAB-studio.h 縮刷版更新
　メールマガジン KAB-studio.h が８０号に達したので縮刷版を更新します。
最近読み始めた方におすすめ。って、最近購読登録数全然増えてないんです
けど（汗）。


/*                          ご注意！！                            */

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


