C言語でconst/literal文字列を連結するにはどうすればよいですか?

C言語で仕事をしているのですが、いくつかのものを連結しなければなりません。

今のところ、次のようなものがあります。

message = strcat("TEXT ", var);

message2 = strcat(strcat("TEXT ", foo), strcat(" TEXT ", bar));

さて、C言語の経験がある方なら、これを実行しようとするとsegmentation faultが発生することに気づくと思います。では、どうやってそれを回避すればいいのでしょうか?

ソリューション

C言語では、"string"は単なる char 配列です。そのため、他の"string"と直接連結することはできません。

これは、srcが指す文字列をdestが指す文字列の末尾に追加するものです。

char *strcat(char *dest, const char *src);

以下はcplusplus.comの例である。

char str[80];
strcpy(str, "these ");
strcat(str, "strings ");
strcat(str, "are ");
strcat(str, "concatenated.");

最初のパラメータには,デスティネーション・バッファそのものを指定する必要があります. デスティネーションバッファは、char配列バッファでなければなりません。 例を挙げるとchar buffer[1024];

**最初のパラメータには、コピーしようとしているものを保存するのに十分なスペースがあることを確認してください。 もし利用可能であれば、以下のような関数を使用すると安全です。もし使用可能であれば、次のような関数を使用した方が安全です: strcpy_sstrcat_s のように、コピー先のバッファのサイズを明示的に指定しなければなりません。

Note:文字列リテラルは定数であるため,バッファとして使用することはできません。文字列リテラルは定数なので,バッファとして使用することはできません.したがって,バッファ用の char 配列を常に確保する必要があります.

strcat`の戻り値は,単に無視しても構いません。これは利便性のために存在するもので,呼び出しを一行のコードにまとめることができます。

strcat(strcat(str, foo), bar);

つまり、あなたの問題は次のように解決できます。

char *foo = "foo";
char *bar = "bar";
char str[80];
strcpy(str, "TEXT ");
strcat(str, foo);
strcat(str, bar);
解説 (14)

文字列リテラルを変更しようとするのは未定義の動作で、以下のようになります。

strcat ("Hello, ", name);

のようなものがそれにあたります。これは、文字列リテラル "Hello, " の末尾に name という文字列を追加しようとするもので、これは十分に定義されていません。

次のようにしてみてください。これであなたがやろうとしていることが実現できます。

char message[1000];
strcpy (message, "TEXT ");
strcat (message, var);

これは、変更が許可されている*バッファ領域を作成して、文字列リテラルと他のテキストの両方をそこにコピーします。ただ、バッファオーバーフローには注意が必要です。入力データを制御する(または事前にチェックする)場合は、私のように固定長のバッファを使っても問題ありません。

そうでない場合は、ヒープから十分なメモリを確保して処理できるようにするなどの緩和策をとるべきです。つまり、次のようなことです。

const static char TEXT[] = "TEXT ";

// Make *sure* you have enough space.

char *message = malloc (sizeof(TEXT) + strlen(var) + 1);
if (message == NULL)
     handleOutOfMemoryIntelligently();
strcpy (message, TEXT);
strcat (message, var);

// Need to free message at some point after you're done with it.
解説 (5)

strcat()の第一引数には、連結された文字列のための十分なスペースを確保する必要があります。そこで、結果を受け取るのに十分なスペースを持つバッファを割り当てます。

char bigEnough[64] = "";

strcat(bigEnough, "TEXT");
strcat(bigEnough, foo);

/* and so on */

strcat()は第2引数と第1引数を連結し、その結果を第1引数に格納します。返されるchar*は単にこの第1引数であり、あなたの便宜のためだけのものです。

第1引数と第2引数を連結して新たに確保された文字列は得られませんが、これはあなたのコードに基づいて期待していたことだと思います。

解説 (0)