char配列構造string


これは古い話題ですが、少し注意しないと間違います.
最近、プラットフォームをまたいで印刷できるプログラムを書いていますが、この問題に遭遇したので、覚えておきます.共に励ます!
char配列でstringを初期化する
#include <string>

using std::string;
using std::cout;

int main(int argc, const char * argv[])
{
    char chArray[] = {'m', 'a', 'r', 'k'};
    cout << "array size = " << sizeof(chArray)/sizeof(char) << endl;
    cout << chArray << endl;
    string str(chArray);
    cout << "str = " << str << " and str's size = " << str.length() << endl;
}

上記のコードに対して、異なるコンパイラの出力結果は一致せず、ランダム性を有する.
macプラットフォームで結果を出力
array size = 4
mark\310\367\277_\377
str = mark\310\367\277_\377 and str's size = 10

こんな結果になったら、まるでfuck...
しかし、出力結果はまたこうなることがあります.
array size = 4
mark
str = mark and str's size = 5
明らかにstringのsizeが間違っています.
考えてみれば、もともと'0'が少なくなって、上のコードを修正しました.
#include <string>

using std::string;
using std::cout;

int main(int argc, const char * argv[])
{
    char chArray[] = {'m', 'a', 'r', 'k', '\0'};
    cout << "array size = " << sizeof(chArray)/sizeof(char) << endl;
    cout << chArray << endl;
    string str(chArray);
    cout << "str = " << str << " and str's size = " << str.length() << endl;
}

出力も正常になりました.
array size = 5
mark
str = mark and str's size = 4

すなわち、char配列はstringオブジェクトを初期化する、配列の終端子'0'を忘れないようにする.
また、stringのsizeはchar配列sizeよりも小さいことに注意する.
上のものがわかりませんが、あなたは理解していますか?
では、次のコード出力は、自分の予想に達すると思いますか?
    const char * cp = str.c_str();
    unsigned long size = str.length();
    char chArray2[size];
    for (int i=0; i<size; i++) {
        chArray2[i] = cp[i];
        cout << chArray2[i] << endl;
    }
    
    string str2(chArray2);
    cout << "str2 = " << str2 << " and str2's size = " << str2.length() << endl;

OK、ここは明らかに間違っています.少なくとも2つは間違っています.
1.chArray 2の大きさ
2.chArray 2の終端に'0'が追加されていません
修正して、完全な例を示します.
#include <string>

using std::string;
using std::cout;

int main(int argc, const char * argv[])
{
    // char[] ---> string
    char chArray[] = {'m', 'a', 'r', 'k', '\0'};
    cout << "array size = " << sizeof(chArray)/sizeof(char) << endl;
    cout << chArray << endl;
    string str(chArray);
    cout << "str = " << str << " and str's size = " << str.length() << endl;
    
    // string --> char[]
    const char * cp = str.c_str();
    unsigned long size = str.length();
    char chArray2[size + 1];
    for (int i=0; i<size; i++) {
        chArray2[i] = cp[i];
        cout << chArray2[i] << endl;
    }
    chArray2[size] = '\0';
    
    string str2(chArray2);
    cout << "str2 = " << str2 << " and str2's size = " << str2.length() << endl;
}

なぜchar配列でstringオブジェクトを構築するのか、char*(ポインタ)を使ったほうがいいのではないかと言う人もいるかもしれません.
確かに、そうですが、時々char配列を操作する必要があります.私も自分が直面した問題をまとめて皆さんと共有します.
サンプルコードの
char chArray[] = {'m', 'a', 'r', 'k', '\0'};

次のように変更
char chArray[] = "mark";

または
const char *chArray = "mark";

コードも正常に正しく出力ことができる.