Standard Library[lib]

C++ string concatenation: +, += and append()

Section
Standard Library [lib]
Standard
C++17
Compilers
MSVC 19.44, Clang 19.1 (MSVC STL), GCC 16.2, Clang 23.1 (libc++)
Published
Length
7 min read
In this answer7 clauses
  1. 1How do you append to a string in C++?
  2. 2Why does "Hello, " + "world" not compile?
  3. 3How do you add a number to a string in C++?
  4. 4How do you join many strings in a loop?
  5. 5What about strcat and C strings?
  6. 6Is std::format better? (C++20)
  7. 7Which one should you use?

Abstract

C++ string concatenation uses + to build a new std::string and += or append() to add to the end of one you already have. At least one side of every + must be a std::string, so “Hello, “ + “world” does not compile. A number goes through std::to_string first: on a std::string, text += 65 compiles but appends the letter A.

Two short strips of hatched character cells, one of three cells and one of four, sit apart; arrows carry them down into one strip of seven cells, where a blue line marks the joint.
Figure 1 — Two pieces, joined end to end.

C++ string concatenation is done with the + operator: first + " " + last builds a new std::string from the pieces and leaves them unchanged. To add to the end of a string you already have, use += or append(). At least one side of every + must be a std::string, and a number has to go through std::to_string first.

[Example 1:
#include <iostream>
#include <string>

int main() {
    std::string first = "Ada";
    std::string last = "Lovelace";

    std::string full = first + " " + last;
    std::cout << full << '\n';  // Ada Lovelace
}

— end example]

It printed:

[Example 2:
Ada Lovelace

— end example]

This answer is written for C++17; the one line that needs C++20 says so. The samples were built with MSVC 19.44, Clang 19.1 (MSVC STL), GCC 16.2 and Clang 23.1 (libc++). All four printed the same for every sample, and the comment on each output line is what it printed.

How do you append to a string in C++?

Use + when you want a new string, and += or append() when you want to make an existing string longer. + leaves both pieces as they were; += adds to the end of the string on its left. append() does what += does for a string or a literal, and can also add part of a string or one character repeated (std::basic_string::append). It has no one-character form, so name.append('!') does not compile: a single character goes on with += '!', push_back('!') or append(1, '!').

Top, first + last: the strips Ada and Lovelace stay as they are and arrows copy both into a third, new strip, AdaLovelace. Bottom, first += last: Lovelace is copied onto the end of first, which now reads AdaLovelace.
Figure 2 — The + operator builds a new string; += makes the one on its left longer.

With first and last from above:

[Example 3:
std::string name = first;
name += " ";                 // a literal
name += last;                // a std::string
std::cout << name << '\n';   // Ada Lovelace
name += '!';                 // one char
std::cout << name << '\n';   // Ada Lovelace!
name.push_back('!');         // one char, the same way
std::cout << name << '\n';   // Ada Lovelace!!

std::string greeting = "Hello, ";
greeting.append(first);          // the whole string
std::cout << greeting << '\n';   // Hello, Ada
greeting.append(3, '!');         // one char, three times
std::cout << greeting << '\n';   // Hello, Ada!!!

std::string handle = "@";
handle.append(first);
handle.append(last, 0, 3);       // 3 chars of last, from 0
std::cout << handle << '\n';     // @AdaLov

— end example]

Why does "Hello, " + "world" not compile?

Because neither side is a std::string. A quoted literal such as "Hello, " is an array of const char: eight of them, seven characters and the '\0' that ends it. For +, C++ turns each array into a pointer to its first character, and two pointers cannot be added.

[Example 4:
std::string greeting = "Hello, " + "world";  // does not compile

— end example]

GCC’s first error line:

[Example 5:
error: invalid operands of types 'const char [8]' and 'const char [6]' to binary 'operator+'

— end example]

MSVC and both Clang builds reject it too. The rule holds for each +, read from the left: "Hello, " + "dear " + first fails at its first + with the same error, while "Hello, " + first + "!" compiles. The fix is to make one side a std::string, by constructing one or with the s suffix, or to drop the +:

[Example 6:
// 1. Make the left side a std::string.
std::string a = std::string("Hello, ") + "world";

// 2. The s suffix makes the literal a std::string.
using namespace std::string_literals;
std::string b = "Hello, "s + "world";

// 3. Side by side, no +: the compiler joins them.
std::string c = "Hello, " "world";

— end example]

All three printed Hello, world. The suffix needs the using directive, which brings std::string_literals into scope. The side-by-side form works for literals only.

How do you add a number to a string in C++?

Convert the number with std::to_string first, then join as usual; converting an int to a string covers the other ways.

[Example 7:
int age = 36;

std::string label = "Age: " + std::to_string(age);
std::cout << label << '\n';  // Age: 36

— end example]

Without the conversion, std::string label = text + 5;, where text is a std::string, does not compile on any of the four: GCC reports no match for 'operator+', MSVC error C2676. Two close relatives do compile, and print something you did not ask for:

[Example 8:
std::string text = "Age: ";
text += 65;                  // the char with code 65, 'A'
std::cout << text << '\n';   // Age: A

std::string tail = "abc" + 1;  // skips the first char
std::cout << tail << '\n';     // bc

— end example]

text += 65 compiles where text + 5 did not because += is a member function that takes a single char, so the int quietly converts to one (std::basic_string::operator+=). The + for strings is a template, written once for every character type, that has to work out one character type from both sides; it cannot make an int fit, so no version of it applies.

"abc" + 1 never meets a std::string: the literal becomes a pointer to its first character, and + 1 moves it one character on (the standard’s rule for +).

You cannot count on a warning: at -Wall -Wextra (/W4 on MSVC), none of the four warned about text += 65, and with an int variable in place of the 65 only MSVC did (C4244). Add -Wconversion and GCC and Clang warn about the variable too. Only the two Clang builds flagged "abc" + 1: adding 'int' to a string does not append to the string.

How do you join many strings in a loop?

Start with an empty string and += each piece, adding the separator before every piece but the first:

[Example 9:
std::vector<std::string> names = {"Ada", "Grace", "Alan"};

std::string joined;
for (std::size_t i = 0; i < names.size(); ++i) {
    if (i > 0) {
        joined += ", ";  // before every name but the first
    }
    joined += names[i];
}
std::cout << joined << '\n';  // Ada, Grace, Alan

std::string first = "Ada";
int age = 36;
double score = 92.5;

std::ostringstream out;
out << first << ", age " << age << ", score " << score;
std::string line = out.str();
std::cout << line << '\n';  // Ada, age 36, score 92.5

— end example]

The second half is for pieces that mix text and numbers: a std::ostringstream, from <sstream>, takes them all with << the way std::cout does, and str() returns a copy of the result as a std::string.

What about strcat and C strings?

std::strcat, from <cstring>, is C’s way: it copies one C string onto the end of another inside a char array you sized yourself, and it does not check that the result fits. If the array is too small, the behavior is undefined, which means the program may do anything (std::strcat).

A correct call, std::strcat(buffer, ", world") into char buffer[32] = "Hello", printed Hello, world on all four. On Windows, MSVC (warning C4996) and Clang both called it unsafe and suggested strcat_s, a warning that comes from the Windows C runtime’s header; GCC and Clang on Linux said nothing.

In C++, use std::string, which grows as needed. A C string can still take part in + as long as the other side is a std::string, as the literal "Age: " did above.

Is std::format better? (C++20)

For text with values in the middle, yes: since C++20, std::format from <format> fills each {} with the next argument, numbers included, and returns a std::string (std::format).

[Example 10:
std::string line = std::format("{} is {}", first, age);  // C++20
std::cout << line << '\n';  // Ada is 36

— end example]

first and age are from above. Build it as C++20 (-std=c++20, or /std:c++20 on MSVC); all four did, and Since When’s C++20 table gives the first GCC, Clang and MSVC release with std::format. Before C++20, the std::ostringstream above does the same job.

Which one should you use?

To Write
Join two or three pieces into a new string first + " " + last
Add to the end of a string name += last
Add one character name += '!' or push_back('!')
Add part of a string, or a repeated character append(last, 0, 3), append(3, '!')
Add a number "Age: " + std::to_string(age)
Join two literals "Hello, "s + "world"
Join many pieces in a loop joined += names[i], as above
Text with values in it std::format (C++20) or std::ostringstream

The rest of std::string, from its length to find(), is in how a C++ string works. Standard library has the other answers on strings and containers.

Questions

Can you add an int to a string in C++?

Not directly. Convert it first: “Age: “ + std::to_string(age) gives “Age: 36″ when age is 36. Without the conversion, text + 5 does not compile, and text += 65 compiles but appends the character with code 65, an A, not the digits.

What is the difference between + and append() in C++?

The + operator builds a new string and leaves both pieces unchanged. append() adds to the end of the string it is called on, as += does, and can also add part of a string, as in s.append(last, 0, 3), or one character repeated, as in s.append(3, ‘!’).

How do you add a character to a string in C++?

Use += with the character in single quotes, name += ‘!’, or call name.push_back(‘!’); both add one char to the end. To add the same character several times, use name.append(3, ‘!’).

Can you concatenate two string literals in C++?

Not with +: “Hello, “ + “world” does not compile, because both sides are arrays of const char, not std::string. Make one side a string, as in std::string(“Hello, “) + “world”, or write “Hello, “s after using namespace std::string_literals. Two literals side by side with no + between them, “Hello, “ “world”, are joined by the compiler.

How do you concat strings with a separator?

Start with an empty std::string and add each piece with += in a loop, adding the separator before every piece except the first. For the names Ada, Grace and Alan with “, “ that gives “Ada, Grace, Alan”, with no separator at either end.

Is += faster than + for strings?

Neither is timed here, so there is no speed claim; what differs is the work. s += t adds t to the end of the string s already has, while s = s + t first builds a new string, a copy of s with t after it, and then replaces s with it.

Sources

  1. operator+ (std::basic_string)cppreference.com
  2. std::basic_string::operator+=cppreference.com
  3. std::basic_string::appendcppreference.com
  4. std::operator””scppreference.com
  5. std::to_stringcppreference.com
  6. std::formatcppreference.com
  7. std::strcatcppreference.com
  8. [expr.add] Additive operatorsC++ standard working draft

Read next

  1. C++ string (std::string) explained with examplesStandard Library · Miriam Castellanos · written for C++17
  2. C++ string length: size(), length() and strlenStandard Library · Miriam Castellanos · written for C++17
  3. C++ string comparison: ==, compare() and strcmpStandard Library · Miriam Castellanos · written for C++17