STL の string を使う

STL string(wstring) の使い方です。

前田稔(Maeda Minoru)の超初心者のプログラム入門

STL string 入門

  1. 文字列(char の配列)で最も悩まされるのは、文字列の長さの問題です。
    必要以上に大きな領域を確保するのも気が引けますし、領域をオーバーしてアクセスすると何が起こるか解りません。
    特にサイズが確定しないメモリ領域をダイナミックにアロケートするときには、何時も悩まされます。
    この問題を一挙に解決してくれるのがストリングです。
    STL のストリング以外にも C++ Maneged Mode や Windows8 や C# でも独自のストリング機能がサポートされていて、それぞれ書き方や機能が異なるので注意が必要です。
  2. 空の Console Application を作成して、次のファイルをプロジェクトに加えて下さい。
    [プロジェクト][プロパティ][構成プロパティ][全般]から文字セットに「マルチバイト文字セットを使用する」を選択します。
    STL string を使うときは using namespace std; を定義します。
    string s がストリングの定義です。
    s の長さは char[256] のように固定長では無く、代入する文字列の長さに合わせてくれます。
    また string への代入には「=」が使えます。
    /*★ STL string のプログラム     前田  稔 ★*/
    #include <iostream>
    #include <string>
    using namespace std;
    
    int main()
    {   string s;
    
        s= "12345";
        cout << "1番目の文字列: " << s << endl;
        s= "abcdefg";
        cout << "2番目の文字列: " << s << endl;
        s= "ABCDEFGHIJKLMN";
        cout << "3番目の文字列: " << s << endl;
        return 0;
    }
    
  3. string で文字列の配列を定義するときは次のように書きます。
        std::string str[15] =
        {   "g cube",
            "v - 5 - 5 - 5",
            "v 5 - 5 - 5",
            "v - 5 5 - 5",
            "v 5 5 - 5",
            "v - 5 - 5 5",
            "v 5 - 5 5",
            "v - 5 5 5",
            "v 5 5 5",
            "f 1 3 4 2",
            "f 1 5 7 3",
            "f 2 4 8 6",
            "f 1 2 6 5",
            "f 3 7 8 4",
            "f 5 6 8 7" };
    

Debug() 関数を定義

  1. STL の string で Debug() 関数を定義します。
    // STL string で Debug() 関数を定義    Maeda Minoru
    #include <iostream>
    #include <string>
    #include <windows.h>    //OutputDebugString
    #include <strsafe.h>    //StringCbPrintf
    using namespace std;
    
    void Debug(string msg, int v)
    {   char  work[80];
        if (StringCbPrintf(work, 80, "%s(%d)\r\n", msg.data(), v) != 0)
            MessageBox(NULL,"CbPrintf Error","Error",MB_OK);
        OutputDebugString(work);
    }
    
  2. Debug() 関数を呼び出します。
        s= "12345";
        cout << "1番目の文字列: " << s << endl;
        Debug(s, s.length());
        s= "abcdefg";
        cout << "2番目の文字列: " << s << endl;
        Debug(s, s.length());
        s= "ABCDEFGHIJKLMN";
        cout << "3番目の文字列: " << s << endl;
        Debug(s, s.length());
    
  3. OutputDebugString を使うときは windows.h をインクルードします。
    StringCbPrintf を使うときは strsafe.h をインクルードします。
    OutputDebugString のデバッグ情報は、出力ウインドウに印字されます。
  4. StringCbPrintf で string msg を編集して char work[80] に格納します。
    work を OutputDebugString() で印字します。

wstring を使う

  1. Store Application では文字列(文字)に16ビットコード(String^)が使われています。
    STL でも16ビットコードに対応した wstring が用意されています。
    #include <windows.h>    // OutputDebugString
    #include <string>       // STL の String を使う
    
    // ',/' で区切られた文字列を数値に変換して vector でリターン
    std::vector<int> MySplit::split(Platform::String^ str)
    {
        std::vector<int> vt;
        std::wstring s;
        std::wstring Word;
        int    Size, Col, wk;
        s = str->Data();
        s += L"/";
        OutputDebugString(s.data());
        Size = s.length() - 1;
        vt.clear();
        for (Col = 0; Col < Size;)
        {
            wk = s.find_first_not_of(L" ,/", Col);
            Col = wk;
            wk = s.find_first_of(L" ,/", Col);
            if (wk==Col)        break;
            Word = Word.assign(s, Col, wk - Col);
            vt.push_back(_wtoi(Word.data()));
            Col = wk + 1;
        }
        return vt;
    }
    
  2. ソースファイルの文字コードは Shift-JIS のままでも構いませんが、私は UTF-8 を使うことにしました。
    [プロジェクト][プロパティ][構成プロパティ][全般]から文字セットに「Unicode 文字セットを使用する」を選択します。
    // STL wstring のプログラム    Maeda Minoru
    #include <windows.h>
    #include <string>
    #include <strsafe.h>    //StringCchPrintf() 
    #include <conio.h>      //_getch()
    using namespace std;
    
    void Debug(wstring msg, int v)
    {   WCHAR  work[80];
        char   wk[80];
        if (StringCchPrintf(work, 80, L"%s(%d)\r\n", msg.data(), v) != 0)
            MessageBox(NULL,L"CchPrintf Error",L"Error",MB_OK);
        OutputDebugString(work);
        WideCharToMultiByte(CP_ACP,0,work,-1,wk,80,NULL,NULL);
        printf(wk);
    }
    
    int main()
    {   wstring s;
    
        s= L"12345";
        Debug(s, s.length());
        s= L"abcdefg";
        Debug(s, s.length());
        s= L"ABCDEFGHIJKLMN";
        Debug(s, s.length());
        _getch();
        return 0;
    }
    
  3. Debug() 関数を呼び出して、OutputDebugString と printf で印字します。
    printf の印字はコンソール画面に、OutputDebugString は出力ウインドウに印字されます。
  4. StringCchPrintf で string msg を編集して WCHAR work[80] に格納します。
    work を OutputDebugString() で印字します。
    OutputDebugString は char[] でも WCHAR[] でも印字出来ますが、printf は char[] しか使えません。
    そこで WideCharToMultiByte() を使って変換しています。
  5. STL の string クラスには、多くのメンバー関数が用意されています。
    STL(Standard Template Library) の後半で、代表的な使い方を抜粋しています。

超初心者のプログラム入門(C/C++)