4

この非常に単純なコード:

#include <iostream>

using namespace std;

void exec(char* option)
{
    cout << "option is " << option << endl;
    if (option == "foo")
        cout << "option foo";
    else if (option == "bar")
        cout << "opzion bar";
    else
        cout << "???";
    cout << endl;
}

int main()
{
    char opt[] = "foo";
    exec(opt);
    return 0;
}

2 つの警告が生成されます。文字列リテラルとの比較により、未指定の動作が発生します。

このコードが正確に機能しない理由を説明できますか?

char opt[]

char *opt

動作しますが、警告が生成されますか? \0 終了と関係ありますか? opt の 2 つの宣言の違いは何ですか? const 修飾子を使用するとどうなりますか? 解決策は、std::string? を使用することです。

4

4 に答える 4

16

char 配列または char ポインターは、実際には C++ の文字列クラス オブジェクトと同じではないため、これは

if (option == "foo")

文字列optionを文字列リテラル "foo" と比較するのではなく、アドレスoption文字列リテラル "foo" のアドレスと比較します。オプションが「foo」と同じかどうかを知りたい場合は、多くの文字列比較関数のいずれかを使用する必要があります。 これを行うための明らかな方法です。または、代わりにstrcmp使用できますstd::stringchar*

于 2010-03-18T10:59:55.040 に答える
4

使用する場合にのみ、演算子を使用==して文字列を比較できますstd::string(これは良い方法です)。C スタイルの char*/char[] 文字列を使用する場合は、C 関数strcmpまたはstrncmp.

を使用して C 文字列std::string::operator ==と比較することもできます。std::string

std string foo = "foo";
const char *bar = "bar";

if (foo == bar) 
   ...
于 2010-03-18T10:55:04.303 に答える
3

それが機能しない理由は、比較が文字列ではなく文字ポインタを比較するためです。

char *を使用すると機能する理由、コンパイラがリテラル文字列 "opt"を一度保存​​し、それを両方の参照に再利用することを決定する可能性があるためです(コンパイラがこれを行うかどうかを示すコンパイラ設定をどこかで見たことがあると思います) )。

char opt []の場合、コンパイラは文字列リテラルをopt配列用に予約されたストレージ領域(おそらくスタック上)にコピーします。これにより、ポインタが異なります。

レンツェ

于 2010-03-18T11:18:49.070 に答える
1

C++ の場合、std::stringソリューションを使用します。

#include <iostream> 
#include <string>

using namespace std; 

void exec(string option) 
{ 
    cout << "option is " << option << endl; 
    if (option == "foo") 
        cout << "option foo"; 
    else if (option == "bar") 
        cout << "option bar"; 
    else 
        cout << "???"; 
    cout << endl; 
} 

int main() 
{ 
    string opt = "foo"; 
    exec(opt);

    exec("bar");

    char array[] = "other";
    exec(array);
    return 0; 
} 

std::string は、char[]、char* などから自分自身を作成する方法を知っているため、これらの方法でも関数を呼び出すことができます。

于 2010-03-18T13:29:42.023 に答える