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;
}

生成两个警告:与字符串文字比较会导致未指定的行为。

你能解释一下为什么这段代码不起作用,但是如果我改变

char opt[]

char *opt

它有效,但会产生警告?它与 \0 终止有关吗?opt的两个声明有什么区别?如果我使用 const 限定符怎么办?解决方案是使用 std::string?

4

4 回答 4

16

char 数组或 char 指针与 C++ 中的字符串类对象并不完全相同,所以这个

if (option == "foo")

不将字符串option与字符串文字“foo”进行比较,而是将其地址与字符串文字“foo”的地址进行比较option。如果您想知道选项是否与“foo”相同,则需要使用众多字符串比较函数之一。 strcmp是这样做的明显方法,或者您可以使用std::string而不是char*

于 2010-03-18T10:59:55.040 回答
4

==只有在使用时才能使用运算符来比较字符串std::string(这是一个很好的做法)。如果使用 C 风格的 char*/char[] 字符串,则需要使用 C 函数strcmpstrncmp.

您还可以使用与 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 回答