2014-10-30 46 views
1

我想知道的是爲什麼將字符串轉換爲char *似乎使新char *不等於它來自的文字字符串。C++ char *使用strdup從字符串轉換不等於原始原始字符串

如果我有:

//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 *,這不會導致此?

+1

char * ==「string」不符合你的想法。它測試以查看char *的地址==常量的地址 – pm100 2014-10-30 15:48:07

回答

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已經在不同的翻譯單元中被賦予文字「樂趣」,則結果將是錯誤的。

printf("(char* convert) == 'fun' -> %d\n", (s_convert == "fun")); 

將存儲在s_convert到字符串「好玩」的地址的地址。如上所述,字符串文字「fun」具有由編譯器選擇的特定地址。它不會與明確複製的字符串進行比較(它與std::string變量不相關)。 strdup創建新分配的內存,所以地址不會與以前內存中存在的任何內容相同。

printf("(string) == (char*) -> %d\n", (s == c)); //does new char* equal original string 

再次,將std::string與C風格的字符串進行比較。這實際上比較了字符串,並檢查s是否包含存儲在地址c的以空字符結尾的字符串,這要歸功於std::string的過載operator==,因此結果爲真。

總結:您觀察到的效果與std::string和以空字符結尾的C風格字符串之間的轉換沒有任何關係。你只是不比較你認爲你比較。如果您想要比較以空字符結尾的「原始」字符串,請使用strcmp;如果您將std::string與其他字詞進行比較,則使用==,您可以下注您期望的結果。

1

始終使用strcmp來比較char *的。

1

strdup複製字符串並返回指向內存中分配的新字符串的指針。該指針的地址與原始字符串不同,因此您可以使用strcmp()比較兩個字符串,但由於這些字符串位於不同的內存位置,所以比較指針將失敗。

5

對於指針,==比較指針值;它無法知道該指針應該指向一個C風格的字符串(而不是單個字符或未終止的數組),並且不會查看它指向的任何內容。由strdup返回的指針不會是任何字符串的地址,因爲該函數的目的是爲字符串的新副本分配內存。

如果你真的必須因爲某種原因而使用C風格的字符串,你可以將它們與strcmp進行比較。但是C++字符串更方便;除非有很好的理由不要使用它們。

0

當您在指針上使用相等運算符時,除非出現過載,否則將比較指針。所以當你做s_convert == "fun"你比較指針s_convert到指向字符串文字"fun"的指針。

它適用於c == "fun"的原因是因爲c已經指向該字符串文字。

0

,您應該使用的

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

代替

c == "fun";