2012-12-03 23 views
18

私のコードでは、「文字列リテラルからchar *への変換は廃止されました」というエラーが発生しています。コードの目的は、pointer-to-pointerを使用してstring1とstring2に単語を割り当て、それを印刷することです。これをどうすれば解決できますか?ここで文字列リテラルから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

あなたのコードを少し編集しました。出力文をスクロールせずに読み取ることができるように出力文を記述し、必要な行をいくつか上に追加します。 –

+0

今後の検索で重複してマークする[文字列リテラルから 'char \ *'への非推奨の変換](http://stackoverflow.com/questions/9650058/deprecated-conversion-from-string-literal-to-char) –

答えて

39

C++文字列リテラルは、あなたが合法的にそれらを変更することはできません意味のconstchar、の配列です。

ポインタに文字列リテラルを暗黙的に割り当てたい場合(暗黙の配列からポインタへの変換を含む)、char*のように、ターゲットポインタをconst char*と宣言する必要があります。ここで

は警告なしでコンパイルコードのバージョンです:

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

A(非const

#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; 
} 

言語はこの制限を課さないなかった場合について考えてみましょう)char*を使用すると、ポインタが指すデータを変更できます。文字列リテラル(暗黙的に文字列の最初の文字へのポインタに変換)を平文char*に割り当てることができれば、そのポインタを使用してコンパイラからの警告なしで文字列リテラルを変更することができます。上記無効なコード、それはを働いていた場合、

Some literal 

を印刷します - そしてそれは実際にいくつかのシステムでそうかもしれません。私のシステムでは、セグメンテーションフォルトが発生すると、リードオンリメモリ(物理ROMではなく、オペレーティングシステムによって読み取り専用としてマークされているメモリ)に書き込もうとするため、このエラーは発生しません。

(余談:文字列リテラルのためのCの規則はCでは、文字列リテラルはcharの配列、ないconst charの配列であるC++の規則と異なっている - しかし、それは未定義の動作をしている変更しようとこれ。 Cであなたが合法的にchar *s = "hello"; s[0] = 'H';を書くことができ、コンパイラが必ずしも不平を言っているわけではないことを意味します - しかし、実行時にプログラムがセグメンテーションフォルトで死ぬことがあります。キーワードが導入されました.C++は当初からconstでしたので、この特定の妥協は必要ありませんでした。)

+0

信じられないほど明確で、才能豊かで、啓発的です。あなたの助けていただきありがとうございます、私はそれが今よりずっと理解しています! –

+0

説明は素晴らしいですが、コードは不明瞭で混乱しています。実際にはteststrings( 'test1'を指すオフセット)とポイントされた文字列を実際に印刷している間に" Test1 "と" Test2 " (テストストールを通して 'test1'を修正したので" Test2 "です) – neuviemeporte

+0

@neuviemeporte:(少し遅れて返信しています)OPのコードに必要な' const'キーワードを追加するだけでした。私は他の修正や改善を試みていませんでした。 –

関連する問題