#pragma twice

KAB-studio > プログラミング > #pragma twice > 215 Version 11.15 文字列配列の拡張

#pragma twice 215 Version 11.15 文字列配列の拡張

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

 Version 11.15
文字列配列の拡張

今まで文字列について見てきたけど、結局は CString とかの文字列クラ
スを使うことになります
コンストラクタとデストラクタがあるから便利ってことよね
もちろんそうなんだけど、文字列クラスを使うとそれ以外にもいっぱいメ
リットがあるんです

・確保と解放を必ず対にして処理してくれる。
・コンストラクタで領域を確保してくれる。
・デストラクタがで解放してくれるからメモリリークしない。
・リサイズ等について気にしなくていい。
・便利なメンバ関数が揃ってる。
・戻り値として返す事ができる。
・演算子を使って操作する事ができる。

うわ、かなりいっぱいあるね
ただ、デメリットもあります

・メモリを確保する関数を選べないクラスがある。
・文字コードが違う場合の処理が難しい。
・結局はある程度仕組みを知らないと危険。
・ C 言語では使えない。

でも少ないね。文字コードとかはまだ先の話っぽいし。メモリを確保する
関数を選べないクラスって?
たとえば CString とか
つかそれしか知らないからダメじゃん……
あと、実は重要なのが C 言語でしか使えないって点。クラスは C++ でし
か使えないからね
 C 言語しか使えない状況ってあるの?
他の人と一緒にプログラム組むときに、その他の人が C++ 使えなかった
ら?
う”……そういうときは C の機能だけでやらなきゃいけないんだ
そういうこと。そういうときは malloc() とか使えばいいわけだけど
教わってるからあたしもできる?
だいたい大丈夫だと思うよ
だいたい?
たとえば

    char *pch = (char *)malloc( strlen( DATA ) + 1 );

ってメモリを確保したとします。で、この文字列に別の文字列をくっつけ
たいっていう場合、どうすればいいのか、とか
あー、そういうのは教わってないもんね
そういうときは、ふたつの文字列の長さを足したサイズだけ malloc() し
て、そこにふたつの文字列をくっつけて入れて、ポインタを置き換えます

やってみた方が早いかな

void Concat()
{
    // このデータが入る領域を確保します。
    const char *const DATA = "あいうえお";
    // 確保。
    char *pch = (char *)malloc( strlen( DATA ) + 1 );
    strcpy( pch, DATA );
    TRACE( "%s\n", pch );

    // これに次の文字列をくっつけます。
    const char *const DATA2 = "かきくけこ";

    // 両方入るサイズだけ確保します。
    char *pchTemp 
        = (char *)malloc
                ( strlen( pch )
                + strlen( DATA2 )
                + 1 
                );
    // まず最初の方をコピー。
    strcpy( pchTemp, pch );
    // 後の方をくっつけます。
    strcat( pchTemp, DATA2 );

    // 最初に取った方を解放。
    free( pch );
    // ポインタを置き換えます。
    pch = pchTemp;
    // これでサイズの拡張が完了しました。

    // 出力。
    TRACE( "%s\n", pch );
    // あいうえおかきくけこ

    // 最後にやっぱり解放します。
    free( pch );
}

長!!
って言っても、実際には同じ事を2度してるようなもんなんだけどね。前
半部分は前と同じだから飛ばして、まずはここ

    // 両方入るサイズだけ確保します。
    char *pchTemp 
        = (char *)malloc
                ( strlen( pch )
                + strlen( DATA2 )
                + 1 
                );

あ、これがふたつの文字列のサイズを足したの、ってことね
そう。これを pchTemp に入れておきます
 pch に入れちゃいけないの?
だって

    // まず最初の方をコピー。
    strcpy( pchTemp, pch );

って感じに元の文字列をコピーしなきゃいけないんだから
そっか。 pch に入れちゃったら前のポインタがなくなっちゃうんだ
これで、 pch と pchTemp には同じ文字列が入ってます。次に

    // 後の方をくっつけます。
    strcat( pchTemp, DATA2 );

この strcat() ってランタイムで文字列をくっつけます
第1引数のに、第2引数のをくっつける、んだよね
そう。これで、 pchTemp の中には "あいうえおかきくけこ" が入ってる
ことになります
ってことはこれでオーケー? でもまだなんかやってるよね

    // 最初に取った方を解放。
    free( pch );
    // ポインタを置き換えます。
    pch = pchTemp;

最初に malloc() してきたのを free() してから、 pch に pchTemp を入
れる……あ! そっか、そうしないと最初に malloc() したのがメモリリー
クするんだ
そういうこと。この辺ちょっとわかりづらいからちゃんと見ておこうか。
たとえば

pch      -> 0x00000001
pchTemp  -> 0x00001001

っていう感じにそれぞれにアドレスが入っていたとします。で、それぞれ
のアドレスの場所には

あいうえお
↑0x00000001

あいうえおかきくけこ
↑0x00001001

っていう感じにメモリに入ってます
で、まず pch の方を free() するんだよね
だから、 0x00000001 のメモリ領域が開放されます

DD DD DD DD DD DD DD DD DD DD
↑0x00000001

あいうえおかきくけこ
↑0x00001001

 DD が入ってるのはデバッグモードだから、ってことで
前回のやつね
でも、この時点では

pch      -> 0x00000001
pchTemp  -> 0x00001001

これは変わってないわけね
もちろん 0x00000001 は使えないけどね。で、実際に使うポインタは 
pch の方だから、 pchTemp のアドレスを入れて

pch      -> 0x00001001
pchTemp  -> 0x00001001

これで、 pch の方に〈あいうえおかきくけこ〉のが入ったことになるわ
けです
 pchTemp の方でくっつけたりして、 pch を解放してから pchTemp のと
入れ替え……めんどくさいねー
というわけで、 CString を使うと簡単

void ConcatWithCString()
{
    // まず最初の文字列を渡します。
    const char *const DATA = "あいうえお";
    const char *const DATA2 = "かきくけこ";

    CString cStr;
    // まず最初の文字列を入れます。
    cStr = DATA;
    // 次に2番目の文字列をくっつけます。
    cStr += DATA2;
    // 出力。
    TRACE( "%s\n", cStr );
    // あいうえおかきくけこ
}

うわ、簡単すぎる……
 CString は = とか += とかで文字列を操作できるからね。なんでできる
のか、というわけで次回に続く!

/*
    Preview Next Story!
*/
メモリの話のあとは、クラスの話ぃ?
ちょっと色々振れすぎてる?
さすがにね
でも、同じ文字列操作の話なんだよ?
どっちも技術的には必要なこと、ってこと?
というわけで次回
< Version 11.16 簡単なクラスを作ってみよう! >
につづく!
作らなくても使えるけど、やっぱり使えなきゃ
ってしてるから必要なことが増えるのよー
まぁ元々いっぱいあるし、必要なことは
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。