views:

672

answers:

9

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.

+10  A: 

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
Ha! I had used strcpy, and strcat and it didn't work but that was the one way I didn't try it, thanks!
Anthoni Caldwell
why did you tag it C++?...
Gregory Pakosz
@Anthoni: You're welcome :)
codaddict
what about char* result; result = calloc(strlen(one)+strlen(two)+1, sizeof(char)); and THEN the strcpy+strcat?
luiscubal
@luiscubal: Yes that would work too...just use a (char*) cast, as calloc returns void*
codaddict
The problem with this answer is the hard coded array size. That's a really bad habit to get into, especially if you don't know what size "one" and "two" are.
Paul Tomblin
In the first example, `strcpy(one,two);` should be `strcat(one,two);` (not that *that* makes it correct, as you correctly point out).
Alok
@Alok: correct it, thanks.
codaddict
what about `sprintf(dest,"%s%s",one,two)` and forget the copy?
Mark
+16  A: 

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;
Prasoon Saurav
Because I am using a library that was coded in C so the functions return const char *
Anthoni Caldwell
Then the tag is misleading.
Prasoon Saurav
Well I am coding it in Cpp.
Anthoni Caldwell
+9  A: 

Using std::string:

#include <string>

std::string result = std::string(one) + std::string(two);
Gregory Pakosz
The second explicit constructor call is not necessary
sellibitze
A: 

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
why do you need dynamic memory?
Luca Matteis
-1 for me, first with the C-way you need to use malloc and free. Then even if you do new then it should be delete[] and not delete.
Naveen
The library I am using is coded in C not C++ so all of the functions return const char * not string.
Anthoni Caldwell
@Naveen, the tag said "C++". If you can't use new and delete, then he shouldn't have used the C++ tag.
Paul Tomblin
+8  A: 

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
+1  A: 

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
If the OP can't use C++, he can't use `new`. And if he can use it, he should use `std::string`, as you say.
Alok
Yes, that's true. Yet, at the time of posting, the original post was only tagged `c++`.
stakx
+1  A: 

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
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
@Steve, indeed :) And writing your own `streambuf` directing output to a char buffer used with `ostream` isn't too difficult either.
Johannes Schaub - litb
+3  A: 

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
how about a c_str() example?
sellibitze
A: 
const char* one = "one";
const char* two = "two";
char result[40];
sprintf(result, "%s%s", one, two);
Jagannath