8

std :: basic_stringに「\0」文字を挿入でき、.length()メソッドは影響を受けないのに、呼び出すchar_traits<char>::length(str.c_str())と最初の「\ 0」文字までの文字列の長さが得られるのはなぜですか?

例えば

string str("abcdefgh");
cout << str.length(); // 8
str[4] = '\0';
cout << str.length(); // 8
cout << char_traits<char>::length(str.c_str()); // 4
4

1 に答える 1

18

素晴らしい質問です!

その理由は、Cスタイルの文字列がヌルバイトで終わるバイトのシーケンスとして定義されているためです。.c_str()C ++からCスタイルの文字列を取得するために使用するとstd::string、C++文字列が格納するシーケンスがnullバイトで返されます。これをに渡すstrlenと、ヌルバイトに達するまでバイトをスキャンし、その前に見つかった文字数を報告します。stringにヌルバイトが含まれている場合、strlen文字列の実際の終わりに到達する前に停止するため、文字列の全長よりも小さい値が報告されます。

重要な詳細は、strlenchar_traits<char>::lengthは同じ機能ではないということです。char_traits<charT>::lengthただし、 (§21.1.1)のC ++ ISO仕様では、trueのような最小値char_traits<charT>::length(s)を返すとされています。の場合、この関数は、比較を行って2つの文字が等しい場合に戻り、書き込みによって文字を作成するとnullバイトが生成されるため、これは「文字列の最初のnullバイトはどこにありますか?」と同じです。この2つは技術的に異なる機能ですが、基本的にはどのように機能するかです。 ichar_traits<charT>::eq(s[i], charT())char_traits<char>eq==char()strlen

ただし、 C ++std::stringは、「任意の文字シーケンス」のより一般的な概念です。その実装の詳細は外界からは隠されていますが、おそらく開始ポインターと停止ポインター、またはポインターと長さのいずれかで表されます。この表現は格納されている文字に依存しないためstd::string、その長さを尋ねると、それらの文字が実際に何であるかに関係なく、そこにある文字の数がわかります。

お役に立てれば!

于 2011-03-16T00:15:33.637 に答える