string operator + (overloaded) different behavior for char array and string.in cpp

Viewed 92

I tried merging 2 arrays using string operator. Following case works fine, + operator accepts char* and string.

    string s = "";;
    char a[5] = { 'f', 'i', 'r', 's', 't' };
    char b[6] = { 's', 'e', 'c', 'o', 'n', 'd' };
    s = a + string(b);

But this case does not work fine when I pass char* and string. I was confused why is it so?

    string s = "";;
    char a[5] = { 'f', 'i', 'r', 's', 't' };
    char b[6] = { 's', 'e', 'c', 'o', 'n', 'd' };
    s = a + "{";

could someone please explain.

2 Answers

Because "{" is not std::string, but const char[2] (including the null terminator char) which could decay to const char*. Then a + "{" is just pointer arithmetic (addition) which is invalid.

You need to change either of the operand to std::string to make the operator+ for std::string to be called. e.g.

a + std::string("{");

or use literals (since C++14).

a + "{"s;

C-style strings have a nul terminator ('\0') at the end. Library code that handles them uses the nul terminator to find the end of the string.

const char *a = "abc";

Here, "abc" is an array of 4 char, as if you had written

const char *a = { 'a', 'b', 'c', '\0' );

If you leave out the '\0' the library code won't know that you are interested only in the three characters that you put in the initializer. It simply won't work right. Formally, the behavior is undefined; anything the program does is legal.

To make this code work right, add a nul terminator to each of the C-style strings:

char a[] = { 'f', 'i', 'r', 's', 't', '\0' };
char b[] = { 's', 'e', 'c', 'o', 'n', 'd', '\0' };

Note that I removed the array size from a[5] and b[6]. The compiler will figure it out from the initializer. The type of a is "array of 6 char", and the type of b is "array of 7 char".

The second problem, even after this is fixed, is that

std::string s = a + "{"

doesn't do what it looks like. "{" is a C-style string (i.e., an array of char). There is no + operator for two C-style strings. To concatenate two C-style strings into an object of type std::string you can either do two separate operations:

std::string s = a;
s += "{";

or you can explicitly convert one (or both) of the C-style strings to std::string:

std::string s = std::string(a) + "{";

I generally prefer the first approach, but the second is certainly reasonable.

Related