字符串文字之间的比较

时间:2010-03-18 10:52:10

标签: c++ string comparison warnings literals

这个非常简单的代码:

#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?

5 个答案:

答案 0 :(得分:12)

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

if (option == "foo")

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

答案 1 :(得分:2)

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

您还可以使用std::string::operator ==std::string与C字符串进行比较:

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

if (foo == bar) 
   ...

答案 2 :(得分:2)

它不起作用的原因是因为比较不比较字符串,而是字符指针。

当你使用char *时可能工作的原因是因为编译器可能决定将文字字符串“opt”存储一次并将其重用于两个引用(我相信我已经看到了编译器设置在哪里,指示编译器是否这样做。)

对于char opt [],编译器将字符串文字复制到为opt数组保留的存储区域(可能在堆栈上),这会导致指针不同。

Renze

答案 3 :(得分:0)

看起来你来自Java / C#:)在C ++中,字符串只是一个存储字符的内存指针,最后是null char。如果字符串“看起来”相等,则它们可能指向内存中的不同区域并且不相等。检查相等性要么使用C ++的类std :: string,要么使用C函数strcmp。

答案 4 :(得分:0)

对于C ++,我会使用std :: string solution

#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 *等创建自己,所以你仍然可以用这些方式调用函数。