Joining two or more strings together is referred to as string concatenation. This tutorial explains different techniques for combining strings in C++ along with examples and performance considerations for each approach.
Why Concatenate Strings?
Here are some common use cases for string concatenation:
- Generate log messages
- Build configuration files
- Assemble SQL queries
- Construct output for display
- Webpage creation by joining HTML strings
Using the + Operator
The + operator provides a simple way to concatenate both string literals and variables:
string s = "Hello " + "World!";
When we concatenating a string variable and literal, the literal gets implicitly converted to a string.
Example:
#include <iostream>
#include <string>
using namespace std;
int main() {
string firstName = "Sara";
string message = "Hello " + firstName;
cout << message;
return 0;
}
Prints: Hello Sara
Performance Implications
Using + creates a temporary string object during concatenation. For repeated usage, it can lead to:
- Additional memory allocations and deallocations on heap
- Slow performance due to copying strings
Therefore, combine strings with + operator only when building short strings.
Concatenation using Append()
The append() method available for string objects concatenates another string without creating a temporary:
string firstName ="John";
firstName.append(" Doe");
Chaining append() calls
string fullName;
fullName.append("John")
.append(" ")
.append("Doe");
Benefits
- Faster as no copies/temporary strings
- Chaining leads to clean code
- Mutable – modifies original string
Example:
#include <iostream>
#include <string>
int main() {
string first = "Hello";
string second = "World";
first.append("!").append(second);
std::cout << first << "\n";
return 0;
}
Prints:
Hello!World
So append() provides good performance for combining multiple strings together into another target string.
Using Concat Function
The string library contains a concat() utility to concatenate two strings:
string result = concat(str1, str2);
Internally it creates a temporary string to hold concatenated value before returning, so not as efficient.
But provides a simple API when limited usage.
Example:
#include <iostream>
#include <string>
using namespace std;
int main() {
string str1 = "Hello";
string str2 = "World!";
string result = concat(str1, str2);
cout << result << endl;
return 0;
}
Prints:
HelloWorld!
So prefer using concat()
where readability is important over raw performance.
Special Considerations
There are some special performance considerations for string concatenation in C++ to keep in mind:
1. Memory Allocation
The common methods for concatenation like + and concat() allocate memory from heap to create new strings.
For limited usage this overhead may not be noticeable. But in tight loops creating hundreds of strings, the temporary memory allocations can significantly slow down program.
To optimize, reuse already allocated string buffer capacity instead of creating new strings repeatedly.
2. Thread Safety
When concatenating strings concurrently from multiple threads, lack of synchronization can cause race conditions.
For thread-safe usage, consider atomic strings or synchronize access to shared strings.
3. Exceptions During Concatenation
Appending user input to strings can potentially throw exceptions that must be handled properly.
For instance, a string stream converting non-numeric input to integer throws an exception:
int n;
stringstream ss;
ss << "invalid";
ss >> n; // throws exception
Wrap risky concatenations in try-catch blocks to handle errors gracefully.
Concatenation in Loops
Building output strings often requires repeatedly appending strings in a loop.
Example:
vector<string> names {"Sara", "Bob", "Alice"};
string result;
for (string n : names) {
result += n + ", ";
}
cout << result;
Prints:
Sara, Bob, Alice,
For better performance with loops:
- Grow capacity to avoid reallocations using reserve()
- Use Stringbuilder instead of plain strings
- Concatenate strings outside loop
Concatenating Numbers and Strings
To join numeric values into strings, explicitly convert them first:
double price = 100.50;
string output = "Product: $" + to_string(price);
Custom types require overload of stream insertion operator:
struct Product {
string name;
float price;
}
ostream& operator<<(ostream& stream, const Product& p) {
return stream << p.name << ":" << p.price;
}
// Now we can concatenate
Product apple{"Apple", 5.99};
string text = "Product is " + apple;
So various data types can be merged into strings through conversions.
Optimizing Concatenation Performance
Excessive string concatenation can significantly degrade performance of CPU intensive programs. Some ways to optimize:
Technique | Description |
---|---|
String Buffer | Class like std::stringbuffer builds string incrementally without reallocating memory. |
Preallocation | For vector of strings – preallocate storage by calling reserve() on vector. |
String Streams | String streams like std::stringstream concatenate strings with internal buffer. |
Batch Concatenation | Concatenate strings less frequently – build strings locally and concat globally. |
By following these best practices, the temporary strings and unnecessary memory allocations can be avoided – leading to faster concatenation performance.
Common Use Cases
Here are some examples of string concatenation in real-world C++ programs:
1. Building HTML Pages
Web applications generate HTML pages by concatenating opening and closing tags with dynamic data:
string page = "<html>";
page += "<body>";
page += // Add content
page += "</body>";
page += "</html>";
2. Log File Messages
Logging engines build informative log messages by joining timestamp, log level, source tags etc:
string message = timestamp + ":[" + level + "]" + source
+ "- " + description;
3. SQL Query Construction
Database code uses concatenation to dynamically construct SQL statements with tables and filter criteria:
string query = "SELECT * FROM " + table;
if (id > 0) {
query += " WHERE id = " + to_string(id);
}
So concatenating strings help generate text outputs, documents, configurations etc. on the fly.
Concatenation of Wide Strings
The same concatenate techniques work for wide string (wstring) data in C++.
For instance:
wstring str1 = L"Hello ";
wstring str2 = L"World!";
wstring result = str1 + str2; // Using +
Or with append:
wstring result;
result.append(L"Hello").append(L"World!");
So all the concatenation options are equally applicable for wide strings. Just use wstring instead of string objects.
Common Mistakes
Some common mistakes to avoid:
- Not handling exceptions from conversions during concatenation
- Assuming concat() or + operator do not create temporary strings
- Using repeated concatenations without capacity planning
- Memory leaks when concatenation buffers are not released
Proper handling of conversions and temporary strings is important for robust and efficient concatenation logic.
Conclusion
In C++, strings can be easily combined together into larger strings through a variety of methods:
- The + operator provides simple syntax but creates temporary strings
- append() method efficiently concatenates without allocations
- concat() function joins two strings with a clean API
By understanding the performance implications of each approach, resource-efficient and scalable string building mechanisms can be developed. Techniques like reserving capacity and using string buffers help optimize high-frequency concatenations.