const char *連結


116

次のような2つのconst charを連結する必要があります。

const char *one = "Hello ";
const char *two = "World";

どうすればいいですか?

char*Cインターフェースを備えたサードパーティのライブラリからこれらのが渡されたため、std::string代わりに単純に使用することはできません。


6
私は混乱しています-元の質問者が「c ++」タグを書いた後、他の誰かがそれを削除しました。この質問の状況はどうですか?C ++コードは許可されますか?
ヨハネスシャウブ-litb

1
@ヨハネス:それはxDより良い質問です。
Prasoon Saurav、2010年

また、元の質問がCを参照していなかったことにも注意してください-そのタグを削除しました。

OPがスタック上の配列strcpystrcat呼び出しを使用する回答を受け入れたため、C ++タグをCに切り替えました。タグを変更することは理にかなっていると思いました。
Gregory Pakosz、2010年

7
C および C ++タグが追加されました。OPがコメントで説明しているように、彼はC ++コードを書いていますが、Cインターフェイスを使用するライブラリを呼び出しています。質問は両方の言語に関連しています。
2010年

回答:


110

あなたの例では12は、 char型の定数を指し、文字ポインタです。これらのポインターが指す文字定数を変更することはできません。したがって、次のようなもの:

strcat(one,two); // append string two to string one.

動作しないでしょう。代わりに、結果を保持するための個別の変数(char配列)が必要です。このようなもの:

char result[100];   // array to hold the result.

strcpy(result,one); // copy string one into the result.
strcat(result,two); // append string two to the result.

7
char *の結果はどうですか。結果= calloc(strlen(one)+ strlen(two)+1、sizeof(char)); そしてstrcpy + strcat?
luiscubal 2010年

3
@luiscubal:はい、それでも機能します... callocがvoid *を返すため、(char *)キャストを使用するだけです
codaddict

5
この回答の問題は、ハードコードされた配列サイズです。特に「1」と「2」のサイズがわからない場合は、これは非常に悪い習慣です。
Paul Tomblin、2010年

1
最初の例では、strcpy(one,two);あるべきstrcat(one,two);(ないことをそれはあなたが正しく指摘するように、それが正しいなります)。
Alok Singhal、2010年

1
sprintf(dest,"%s%s",one,two)コピーについてはどうですか?
mpen

81

Cの方法:

char buf[100];
strcpy(buf, one);
strcat(buf, two);

C ++の方法:

std::string buf(one);
buf.append(two);

コンパイル時の方法:

#define one "hello "
#define two "world"
#define concat(first, second) first second

const char* buf = concat(one, two);

31

C ++を使用している場合はstd::string、Cスタイルの文字列の代わりに使用してみませんか?

std::string one="Hello";
std::string two="World";

std::string three= one+two;

この文字列をC関数に渡す必要がある場合は、単に three.c_str()


7
私はC言語でコーディングされたライブラリを使用していますのでその機能は、* constの文字を返す
Anthoniコールドウェル

1
@AnthoniCaldwell:笑ってくれてありがとう。私は仕事のプレッシャーのためにできませんでした。
D

新しい仕事の時間のよう
最大


17
const char *one = "Hello ";
const char *two = "World";

string total( string(one) + two );

// to use the concatenation as const char*, use:
total.c_str()

更新:パフォーマンス上の理由からに変更 string total = string(one) + string(two);string total( string(one) + two );れました(文字列2と一時的な文字列合計の構築を回避します)

// string total(move(move(string(one)) + two));  // even faster?

@iburidu測った?安全性がパフォーマンスに勝る状況はどうですか?(これらは一般的な状況です)
Sqeaky 2015

3
@Sqeakyこれが他のどのソリューションよりも安全である状況は絶対にありませんが、ランタイム動作を呼び出し、ほぼ確実にメモリ割り当てを呼び出すことにより、コンパイル時のソリューションよりも常に遅くなります。
アリス

8

もう1つの例:

// calculate the required buffer size (also accounting for the null terminator):
int bufferSize = strlen(one) + strlen(two) + 1;

// allocate enough memory for the concatenated string:
char* concatString = new char[ bufferSize ];

// copy strings one and two over to the new buffer:
strcpy( concatString, one );
strcat( concatString, two );

...

// delete buffer:
delete[] concatString;

ただし、C ++標準ライブラリを特に使用したくない、または使用できない場合を除いて、使用する方std::stringがおそらく安全です。


1
OPがC ++を使用できない場合、OPは使用できませんnew。そして、彼がそれを使用できるならstd::string、あなたが言うように、彼はを使用するべきです。
Alok Singhal、2010年

5

CライブラリでC ++を使用しているようです。そのため、で作業する必要がありますconst char *

それらconst char *std::string次のようにラップすることをお勧めします。

const char *a = "hello "; 
const char *b = "world"; 
std::string c = a; 
std::string d = b; 
cout << c + d;

5

まず、動的なメモリ空間を作成する必要があります。次に、2つの文字列をstrcatするだけです。または、C ++の「文字列」クラスを使用できます。古い学校のCの方法:

  char* catString = malloc(strlen(one)+strlen(two)+1);
  strcpy(catString, one);
  strcat(catString, two);
  // use the string then delete it when you're done.
  free(catString);

新しいC ++の方法

  std::string three(one);
  three += two;

なぜ動的メモリが必要なのですか?
Luca Matteis、2010年

4
-1私にとって、最初にC-wayでmallocとfreeを使用する必要があります。そして、あなたが新しいことをしたとしても、それは削除ではなく削除[]でなければなりません。
Naveen、2010年

私が使用しているライブラリはC ++ではなくCでコーディングされているため、すべての関数は文字列ではなくconst char *を返します。
Anthoni Caldwell

1
@Naveen、タグは「C ++」を言った。newとdeleteを使用できない場合、彼はC ++タグを使用するべきではありませんでした。
Paul Tomblin、2010年

5

文字列のサイズがわからない場合は、次のようにすることができます。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(){
    const char* q1 = "First String";
    const char* q2 = " Second String";

    char * qq = (char*) malloc((strlen(q1)+ strlen(q2))*sizeof(char));
    strcpy(qq,q1);
    strcat(qq,q2);

    printf("%s\n",qq);

    return 0;
}

3

使用できますstrstream。これは正式には非推奨ですが、C文字列を操作する必要がある場合には優れたツールであると思います。

char result[100]; // max size 100
std::ostrstream s(result, sizeof result - 1);

s << one << two << std::ends;
result[99] = '\0';

これはストリームに書き込んでoneからtwo、を使用して終了\0を追加しますstd::ends。両方の文字列が正確に99文字\0を書き込むことになる場合があるので、スペースが残っていないため、最後の位置に手動で1つ書き込みます。


廃止はあまり重要ではありません。標準の将来のバージョンから削除されたとしても、独自の名前空間に再実装することはそれほど多くの作業ではありません。
スティーブジェソップ

@Steve、確かに:)でstreambuf使用されるcharバッファに独自の出力を書き込むostreamこともそれほど難しくありません。
Johannes Schaub-litb


0

メモリの動的割り当てでstrcpyコマンドを使用せずに2つの定数文字ポインターを接続する:

const char* one = "Hello ";
const char* two = "World!";

char* three = new char[strlen(one) + strlen(two) + 1] {'\0'};

strcat_s(three, strlen(one) + 1, one);
strcat_s(three, strlen(one) + strlen(two) + 1, two);

cout << three << endl;

delete[] three;
three = nullptr;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.