1

我想知道为什么将字符串转换为 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*?

4

6 回答 6

5

对于指针,==比较指针值;它无法知道指针应该指向 C 风格的字符串(而不是单个字符或未终止的数组),并且不查看它指向的任何内容。返回的指针strdup不会是任何字符串文字的地址,因为该函数的目的是为字符串的新副本分配内存。

如果你真的因为某种原因必须弄乱 C 风格的字符串,你可以将它们与strcmp. 但是 C++ 字符串要方便得多;除非有很好的理由不使用它们。

于 2014-10-30T15:48:06.300 回答
2

让我们一一进行比较:

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

同样,将 anstd::string与 C 风格的字符串进行比较。这确实比较了字符串并检查是否包含由于重载而s存储在地址处的以空字符结尾的字符串,因此结果为真。coperator==std::string

总结一下:您观察到的效果与以std::string空结尾的 C 样式字符串之间的转换无关或几乎没有关系。你只是不比较你认为你比较的东西。如果strcmp您想比较以 null 结尾的“原始”字符串,或者在与其他字符串==进行比较时使用,那么std::string您将获得预期的结果。

于 2014-10-30T15:57:03.113 回答
1

总是strcmp用来比较char *的。

于 2014-10-30T15:45:36.307 回答
1

strdup 复制字符串并返回指向内存中分配的新字符串的指针。该指针与原始字符串的地址不同,因此您可以使用 strcmp() 比较两者,但由于这些字符串所在的内存位置不同,比较指针会失败。

于 2014-10-30T15:46:09.343 回答
0

当您对指针使用相等运算符时,除非有重载,否则它将比较指针。因此,当您s_convert == "fun"指针 s_convert与指向字符串文字的指针进行比较时"fun"

它起作用的原因c == "fun"是因为c已经指向该字符串文字。

于 2014-10-30T15:48:23.130 回答
0

你应该使用

0 == strcmp( c, "fun" );

代替

c == "fun";
于 2014-10-30T15:51:01.670 回答