const char *串联


116

我需要串联两个这样的const字符:

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

我该怎么做呢?

char*从具有C接口的第三方库传递了这些,所以我不能简单地使用它们std::string


6
我很困惑-原始提问者写了“ c ++”标签-然后其他人删除了它。这个问题的状况如何?是否允许使用C ++代码?
Johannes Schaub-litb 2010年

1
@Johannes:这是xD更好的问题。
Prasoon Saurav,2010年

另请注意,原始问题与C无关-我已删除了该标签。

我将C ++标记切换为C,因为OP接受了一个使用堆栈上的数组strcpystrcat调用的答案,我认为更改标记是有意义的。
格雷戈里·帕科斯

7
添加了C C ++标签。正如OP在评论中解释的那样,他正在编写C ++代码,但是调用了一个使用C接口的库。这个问题与两种语言都有关。
jalf

Answers:


110

在您的示例中,一个两个是char指针,它们指向char常量。您不能更改这些指针指向的char常量。所以像这样:

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

不管用。相反,您应该有一个单独的变量(字符数组)来保存结果。像这样:

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(一个)+ strlen(两个)+1,sizeof(字符)); 然后是strcpy + strcat?
luiscubal 2010年

3
@luiscubal:是的,也行得通...只需使用(char *)
强制转换

5
这个答案的问题是硬编码的数组大小。这是一个非常不好的习惯,特别是如果您不知道“一个”和“两个”的大小时。
Paul Tomblin'1

1
在第一个例子,strcpy(one,two);应该是strcat(one,two);(不,使得它正确的,因为你正确地指出)。
Alok Singhal'1

1
怎么办sprintf(dest,"%s%s",one,two),忘记副本?
mpen 2010年

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::stringC样式的字符串呢?

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

std::string three= one+two;

如果您需要将此字符串传递给C函数,只需传递 three.c_str()


7
因为我使用的是用C编码的库,所以函数返回const char *
Anthoni Caldwell,2010年

1
@AnthoniCaldwell:感谢您的笑声。我不能因为工作压力
而死。:D

听起来是时候该
Max


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 );性能方面的原因(避免串两个临时串共建设)

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

@iburidu你测量了吗?在安全胜过性能的情况下呢?(常见的情况)
Sqeaky

3
@Sqeaky绝对不存在比其他解决方案更安全的情况,但是通过调用运行时行为以及几乎可以肯定的是调用内存分配,它总是比编译时解决方案慢。
爱丽丝

8

再举一个例子:

// 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 ++,那么他就不能使用new。如果他可以使用它,则应该使用std::string,如您所说。
Alok Singhal'1

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

首先,您必须创建一些动态内存空间。然后,您可以将两个字符串插入其中。或者,您可以使用c ++“ string”类。老式的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;

为什么需要动态内存?
卡·马蒂斯

4
对我来说-1,首先使用C方式,您需要使用malloc和free。然后,即使您执行了new操作,也应该将它设为delete []而不是删除。
Naveen

我正在使用的库是用C而不是C ++编码的,因此所有函数都返回const char *而不是字符串。
Anthoni Caldwell,2010年

1
@Naveen,标记说“ C ++”。如果您不能使用new和delete,那么他不应该使用C ++标记。
Paul Tomblin'1

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-我们将在最后一个位置手动写一个。


弃用不应该太大。即使将其从标准的将来版本中删除,在您自己的名称空间中重新实现也没有太多工作。
史蒂夫·杰索普

@Steve,的确是:)并且将自己的streambuf定向输出写入与一起使用的char缓冲区ostream也不太困难。
Johannes Schaub-litb 2010年

3
const char* one = "one";
const char* two = "two";
char result[40];
sprintf(result, "%s%s", one, two);

0

在动态分配内存时不使用strcpy命令连接两个常量char指针:

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;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.