2012-12-03 61 views
18

我一直在我的代碼中收到錯誤「從字符串文字轉換爲char *已棄用」。代碼的目的是使用指針指針將string1和string2分配給一個單詞,然後將其打印出來。我怎樣才能解決這個問題?從字符串文字轉換爲char *已棄用

這裏是我的代碼:常量char,這意味着你不能合法地修改它們的

#include <iostream> 
using namespace std; 

struct WORDBLOCK 
{ 
    char* string1; 
    char* string2; 
}; 

void f3() 
{ 
    WORDBLOCK word; 

    word.string1 = "Test1"; 
    word.string2 = "Test2"; 


    char *test1 = word.string1; 
    char *test2 = word.string2; 

    char** teststrings; 

    teststrings = &test1; 
    *teststrings = test2; 

    cout << "The first string is: " 
     << teststrings 
     << " and your second string is: " 
     << *teststrings 
     << endl; 
} 
+1

我已經編輯了一下你的代碼,reforma使輸出語句可以在不滾動的情況下讀取,並在頂部添加一些必要的行。 –

+0

標記爲未來搜索的重複[不贊成將字符串文字轉換爲'char \ *'](http://stackoverflow.com/questions/9650058/deprecated-conversion-from-string-literal-to-char) –

回答

39

C++字符串字面量是數組。

如果要安全地將字符串文字分配給指針(涉及隱式數組指針轉換),則需要將目標指針聲明爲const char*,而不僅僅是char*

這裏有一個版本的代碼,如果沒有警告編譯:

#include <iostream> 

using namespace std; 

struct WORDBLOCK 
{ 
    const char* string1; 
    const char* string2; 
}; 

void f3() 
{ 
    WORDBLOCK word; 

    word.string1 = "Test1"; 
    word.string2 = "Test2"; 

    const char *test1 = word.string1; 
    const char *test2 = word.string2; 

    const char** teststrings; 

    teststrings = &test1; 
    *teststrings = test2; 

    cout << "The first string is: " 
     << teststrings 
     << " and your second string is: " 
     << *teststrings 
     << endl; 
} 

考慮一下,如果語言沒有強加這一限制可能會發生什麼:

#include <iostream> 
int main() { 
    char *ptr = "some literal"; // This is invalid 
    *ptr = 'S'; 
    std::cout << ptr << "\n"; 
} 

A(非constchar*可讓您修改指針指向的數據。如果您可以將一個字符串文字(隱式轉換爲指向該字符串的第一個字符的指針)分配給一個普通的char*,那麼您可以使用該指針修改字符串文本,而不需要編譯器的警告。上面的代碼無效,如果它的工作,將打印

Some literal 

- 它實際上可能在某些系統上這樣做。然而,在我的系統中,它會因分段錯誤而死,因爲它試圖寫入只讀內存(不是物理ROM,而是被操作系統標記爲只讀的內存)。

(一種一旁:C對字符串文字規則是從C++的規則不同。在C,一個字符串文字是char陣列,const char陣列 - 但試圖修改它有未定義的行爲此。意味着在C語言中你可以合法編寫char *s = "hello"; s[0] = 'H';,編譯器不一定會抱怨 - 但是當你運行程序時,程序可能會因分段錯誤而死亡。這樣做是爲了保持向後兼容const之前寫入的C代碼關鍵字被引入,C++從一開始就有const,所以這種特殊的折衷是沒有必要的。)

+0

這是令人難以置信的清晰,機智和啓發。謝謝你的幫助,我現在明白它好多了! –

+0

這個解釋很棒,但是代碼不清晰且令人困惑 - 看起來您希望在打印Testtrings的值(指向'test1'的偏移量)和指向的字符串時打印「Test1」和「Test2」 to'test1'(因爲你通過teststrings修改'test1',所以它是「Test2」) – neuviemeporte

+0

@neuviemeporte :(我知道我有點晚回覆。)我所做的只是在OP的代碼中添加需要的'const'關鍵字。我沒有嘗試做任何其他更正或改進。 –