我想知道为什么将字符串转换为char *似乎使新char *不等于它来自的字符串。
如果我有:
//raw versions of the string:
string s = "fun";
char* c = "fun";
char* s_convert = strdup(s.c_str()); //converting the string to char*
printf("(string) == 'fun' -> %d\n", (s == "fun"));
printf("(char*) == 'fun' -> %d\n", (c == "fun"));
printf("(char* convert) == 'fun' -> %d\n", (s_convert == "fun"));
printf("(string) == (char*) -> %d\n", (s == c)); //does new char* equal original string
产生
(string) == 'fun' -> 1 //true
(char*) == 'fun' -> 1 //true
(char* convert) == 'fun' -> 0 //false
(string) == (char* convert) -> 1 //true
因此转换后的char *仍然等于它来自的原始字符串。但由于某些原因,char* s_convert
不等于它来自的文字字符串,尽管原始的string s
确实如此。
为什么会这样?还有一种更好的方法可以将字符串转换为char *而不会导致这种情况吗?
答案 0 :(得分:5)
对于指针,==
比较指针值;它无法知道指针应该指向C风格的字符串(而不是单个字符或未终止的数组),并且不会查看它指向的任何内容。 strdup
返回的指针不是任何字符串文字的地址,因为该函数的目的是为字符串的新副本分配内存。
如果由于某种原因你真的必须使用C风格的字符串,你可以将它们与strcmp
进行比较。但C ++字符串更方便;使用它们,除非有充分的理由不这样做。
答案 1 :(得分:1)
始终使用strcmp
来比较char *
&#39>。
答案 2 :(得分:1)
strdup复制字符串并返回指向内存中分配的新字符串的指针。此指针的地址与原始字符串的地址不同,因此您可以使用strcmp()比较两者,但由于这些字符串所处的内存位置不同,比较指针将失败。
答案 3 :(得分:1)
让我们逐一进行比较:
printf("(string) == 'fun' -> %d\n", (s == "fun"));
将std::string
变量与字符串文字进行比较。按预期工作(即真正检查s
是否包含字符串“fun”),因为std::string
为此目的而重载operator==
。
printf("(char*) == 'fun' -> %d\n", (c == "fun"));
将c
中存储的地址与字符串文字“fun”的地址进行比较。结果可能是真或假。在你的情况下,这是真的,因为编译器优化了你的代码:它看到你多次使用“fun”,并且只将字符串文字一次存储在内存中,所以地址总是相同的。例如,如果c
在不同的翻译单元中被分配了文字“fun”,则结果将是错误的。
printf("(char* convert) == 'fun' -> %d\n", (s_convert == "fun"));
将s_convert
中存储的地址与字符串文字“fun”的地址进行比较。如上所述,字符串文字“fun”具有编译器选择的特定地址。它不会与明确复制的字符串进行比较(它与std::string
变量无关)。 strdup
创建新分配的内存,因此地址不会与之前存在的任何内容相等。
printf("(string) == (char*) -> %d\n", (s == c)); //does new char* equal original string
再次,将std::string
与C风格的字符串进行比较。这实际上比较了字符串,并检查s
是否包含存储在地址c
的以空字符结尾的字符串,这要归功于operator==
std::string
的重载,因此结果为真。
总结:您观察到的效果与std::string
和以null结尾的C风格字符串之间的转换无关或几乎没有关系。你只是不比较你认为你比较的东西。如果您想比较以空值终止的“原始”字符串,请使用strcmp
,或者在将==
与其他内容进行比较时使用std::string
,并且您会打赌您期望的结果。
答案 4 :(得分:0)
当你在指针上使用相等运算符时,除非存在重载,否则它将比较指针。因此,当您执行s_convert == "fun"
时,将指针 s_convert
与指向字符串文字"fun"
的指针进行比较。
它适用于c == "fun"
的原因是因为c
已经指向该字符串文字。
答案 5 :(得分:0)
你应该使用
0 == strcmp( c, "fun" );
而不是
c == "fun";