2016-09-17 18 views
1

を比較するとき、私はこれらの2つの文字列を比較しています:"code""test"予期しない結果文字列

私はVisual Studioで、この入力すると:

cout<<("t"<"c")<<endl; 
cout<<("c"<"t")<<endl; 
cout<<("code"<"test")<<endl; 
cout<<("test"<"cose")<<endl; 

を結果は次のとおりです。

1 
0 
1 
1 

んどの理想ではありません。私がideone.comで試してみると、結果は

0 
1 
1 
1 

ここで何が問題になりますか?

答えて

4

文字列ではなくポインタ値を比較しています(注:"cose""code"とは異なるリテラルであり、異なるポインタを与えることを保証しています)。

<string>ヘッダーのstd::stringを使用すると、意味のある文字列操作が得られます。

次に、"code"sのようなリテラルを使用することもできます。正式

#include <iostream> 
#include <string> 
using namespace std; 

auto main() -> int 
{ 
    cout << boolalpha; 
    cout << ("t"s < "c"s) << endl; 
    cout << ("c"s < "t"s) << endl; 
    cout << ("code"s < "test"s) << endl; 
    cout << ("test"s < "cose"s) << endl; 
} 

問題のコード、

cout<<("t"<"c")<<endl; 
cout<<("c"<"t")<<endl; 
cout<<("code"<"test")<<endl; 
cout<<("test"<"cose")<<endl; 

&hellip;同じタイプの点の二つのポインタpqの場合

:実装定義された挙動を有し、なぜなら

C++ 11§5.9/ 2 2 NDダッシュ(expr.rel)同じオブジェクトまたは同じ配列の要素または異なる機能のメンバーではない異なるオブジェクト、またはそのうちの1つだけがnullの場合、p<q,p>q,p<=qおよびp>=qの結果は不定です。

ため

C++ 11 20.8.5/8(比較)ただし、std::lessと家族を経由して、明確に定義された方法で、このようなポインタを比較することができます:

をテンプレートgreater,less,greater_equalおよびless_equalの場合、組み込み演算子<,>,<=>=はありません。

しかし、ポインタの比較はいくつかの状況では役に立ちますが、おそらく文字列リテラルを比較したかったでしょう。標準ライブラリは、例えば、 strcmpこれを行うには。しかし、最初に述べたように、std::stringを使用することをお勧めします。


リテラル"code"char数値の不変ヌルで終了する文字列です。最後のヌルバイトでは合計で5つのcharの値になります。従ってタイプはchar const[5]です。

ポインタが期待される文脈で使用される式として、この配列(すなわち、"code"リテラル)を表す式は、最初の項目であるchar const*ポインタへのポインタに減衰します。

これはポインタへの配列式の通常の減衰ですが、C++ 03以前では、崩壊をただちにchar*(no const)にする特別なルールもありました。


注:
2つの同一の文字列リテラルを使用するコンパイラやオプションに応じて、異なるポインタ、または同じポインタを与えることができます¹。

2

などの文字列リテラル。 "t"は、実際には文字の連続した配列(ターミネータを含む)です。

文字列リテラルを使用すると、最初の文字へのポインタが得られます。

したがって、"t" < "c"を実行すると、無関係な2つのポインタが比較されます。 "t" < "c"が真であるかどうかは、コンパイラが文字列リテラル配列を配置する場所に依存します。

文字列を比較する場合は、std::stringまたは古いC関数strcmpを使用する必要があります。

+0

"文字列リテラルを使用すると、最初の文字へのポインタが得られます。"これはしばしば真実ですが、一般的にはそうではありません。 –