145

I need to concatenate two const chars like these:

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

How might I go about doing that?

I am passed these char*s from a third-party library with a C interface so I can't simply use std::string instead.

jalf
  • 243,077
  • 51
  • 345
  • 550
Anthoni Caldwell
  • 1,485
  • 2
  • 10
  • 4
  • 6
    I'm confused - the original questioner wrote "c++" tag - then someone else removed it. What's the state of affairs for this question? Is C++ code allowed? – Johannes Schaub - litb Jan 03 '10 at 14:26
  • 1
    @Johannes: That's a better question xD. – Prasoon Saurav Jan 03 '10 at 14:28
  • Also note the original question did NOT refer to C - I've removed that tag. –  Jan 03 '10 at 14:32
  • I switched the C++ tag to C because the OP accepted an answer that uses arrays on stack and `strcpy` and `strcat` calls, I thought that made sense to change the tags. – Gregory Pakosz Jan 03 '10 at 14:59
  • 9
    Added C *and* C++ tags. As the OP explains in a comment, he's writing C++ code, but calling a library which uses a C interface. The question is relevant in both languages. – jalf Jan 04 '10 at 01:10

13 Answers13

131

In your example one and two are char pointers, pointing to char constants. You cannot change the char constants pointed to by these pointers. So anything like:

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

will not work. Instead you should have a separate variable(char array) to hold the result. Something like this:

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.
codaddict
  • 445,704
  • 82
  • 492
  • 529
93

The C way:

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

The C++ way:

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

The compile-time way:

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

const char* buf = concat(one, two);
Idan K
  • 20,443
  • 10
  • 63
  • 83
  • 2
    It is worth mentioning that the "compile-time" way only works when `one` and `two` are both string literals. – cartoonist Sep 28 '20 at 10:11
34

If you are using C++, why don't you use std::string instead of C-style strings?

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

std::string three= one+two;

If you need to pass this string to a C-function, simply pass three.c_str()

Mooing Duck
  • 64,318
  • 19
  • 100
  • 158
Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
27

Using std::string:

#include <string>

std::string result = std::string(one) + std::string(two);
Gregory Pakosz
  • 69,011
  • 20
  • 139
  • 164
22
const char *one = "Hello ";
const char *two = "World";

string total( string(one) + two );

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

Updated: changed string total = string(one) + string(two); to string total( string(one) + two ); for performance reasons (avoids construction of string two and temporary string total)

// string total(move(move(string(one)) + two));  // even faster?
Pedro Reis
  • 1,587
  • 1
  • 19
  • 19
  • @iburidu have you measured it? What about situations where safety trumps performance? (They are common situations) – Sqeaky Aug 18 '15 at 14:51
  • 3
    @Sqeaky There are absolutely no situations where this is safer than any other solution, but it is ALWAYS slower than a compile time solution, by invoking runtime behavior as well as almost certainly invoking memory allocation. – Alice Aug 25 '15 at 06:26
10

One more example:

// 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;

But unless you specifically don't want or can't use the C++ standard library, using std::string is probably safer.

stakx - no longer contributing
  • 83,039
  • 20
  • 168
  • 268
5

First of all, you have to create some dynamic memory space. Then you can just strcat the two strings into it. Or you can use the c++ "string" class. The old-school C way:

  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);

New C++ way

  std::string three(one);
  three += two;
Paul Tomblin
  • 179,021
  • 58
  • 319
  • 408
5

It seems like you're using C++ with a C library and therefore you need to work with const char *.

I suggest wrapping those const char * into std::string:

const char *a = "hello "; 
const char *b = "world"; 
std::string c = a; 
std::string d = b; 
cout << c + d;
Luca Matteis
  • 29,161
  • 19
  • 114
  • 169
5

If you don't know the size of the strings, you can do something like this:

#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;
}
Anoroah
  • 1,987
  • 2
  • 20
  • 31
3

You can use strstream. It's formally deprecated, but it's still a great tool if you need to work with C strings, i think.

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

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

This will write one and then two into the stream, and append a terminating \0 using std::ends. In case both strings could end up writing exactly 99 characters - so no space would be left writing \0 - we write one manually at the last position.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • Deprecation shouldn't matter too much. Even if it's removed from a future version of the standard, it's not so much work to re-implement in your own namespace. – Steve Jessop Jan 03 '10 at 17:46
  • @Steve, indeed :) And writing your own `streambuf` directing output to a char buffer used with `ostream` isn't too difficult either. – Johannes Schaub - litb Jan 03 '10 at 17:58
3
const char* one = "one";
const char* two = "two";
char result[40];
sprintf(result, "%s%s", one, two);
Jagannath
  • 3,995
  • 26
  • 30
0

Connecting two constant char pointer without using strcpy command in the dynamic allocation of memory:

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;
0

There is a C-style trick for achieving the (const/constexpr) string literals concatenation in build time. It should not matter because const char* are actually C-style stuff anyhow. And without dynamic allocations, strlen, and all the ugly stuff posted here. Everything is done by the compiler, nothing during execution.

The trick is to use the preprecessor #define directive.

#define PREFIX "/dev/"
#define DEVICE PREFIX "pts/3"

constexpr const char* defaultDevice = DEVICE;

This should assign /dev/pts/3 to the variable (without any blank between the 2 preprocessor macros).

carnicer
  • 494
  • 3
  • 9