C++ Strings: Complete Guide with Built-in Functions
Master the C++ string class with comprehensive examples, built-in functions reference table, and advanced string manipulation techniques.
Creation
String Initialization
Manipulation
Modify & Transform
Search
Find & Replace
Comparison
Compare Strings
Introduction to C++ Strings
C++ provides a powerful string class in the <string> header that makes string handling much easier than C-style character arrays. The string class manages memory automatically and provides numerous member functions for string manipulation.
Key Advantages
- Automatic memory management
- Rich set of member functions
- Operator overloading (+, =, ==, etc.)
- Compatible with STL algorithms
- Bounds checking with
at() - Iterators for traversal
Essential Headers
#include <string> // string class
#include <iostream> // Input/output
#include <cctype> // Character functions
#include <algorithm> // STL algorithms
#include <sstream> // String streams
C++ string vs C-style strings
C++ string: std::string str = "Hello"; (Safe, feature-rich)
C-style: char str[] = "Hello"; (Manual memory, limited functions)
#include <iostream>
#include <string>
using namespace std;
int main() {
// Creating strings
string str1 = "Hello, World!";
string str2("C++ Strings");
string str3(10, '*'); // "**********"
// Basic operations
cout << "str1: " << str1 << endl;
cout << "str2: " << str2 << endl;
cout << "str3: " << str3 << endl;
// Length and capacity
cout << "Length of str1: " << str1.length() << endl;
cout << "Capacity of str1: " << str1.capacity() << endl;
// String concatenation
string greeting = "Hello" + string(" ") + "World";
cout << "Greeting: " << greeting << endl;
// String comparison
if (str1 == "Hello, World!") {
cout << "Strings are equal" << endl;
}
// Substring
string sub = str1.substr(7, 5); // "World"
cout << "Substring: " << sub << endl;
// Character access
cout << "First character: " << str1[0] << endl;
cout << "Last character: " << str1.back() << endl;
return 0;
}
Complete C++ String Functions Reference
The following table provides a comprehensive reference of all C++ string class member functions with examples and descriptions:
| Function | Syntax | Description | Return Type |
|---|---|---|---|
| Creation & Initialization | |||
| Constructor | string() |
Default constructor, creates empty string | constructor |
| Constructor | string(const char* s) |
From C-style string | constructor |
| Constructor | string(size_t n, char c) |
Creates string of n copies of character c | constructor |
| Copy Constructor | string(const string& str) |
Copy constructor | constructor |
| Capacity Functions | |||
length() |
str.length() |
Returns number of characters in string | size_t |
size() |
str.size() |
Same as length() | size_t |
capacity() |
str.capacity() |
Returns size of allocated storage | size_t |
empty() |
str.empty() |
Returns true if string is empty | bool |
resize() |
str.resize(n, c) |
Resizes string to n characters | void |
reserve() |
str.reserve(n) |
Requests capacity change | void |
shrink_to_fit() |
str.shrink_to_fit() |
Reduces capacity to fit size (C++11) | void |
| Element Access | |||
operator[] |
str[index] |
Access character (no bounds checking) | char& |
at() |
str.at(index) |
Access character with bounds checking | char& |
front() |
str.front() |
Returns first character (C++11) | char& |
back() |
str.back() |
Returns last character (C++11) | char& |
| Modification Functions | |||
append() |
str.append(s) |
Appends string to the end | string& |
push_back() |
str.push_back(c) |
Appends character to the end | void |
pop_back() |
str.pop_back() |
Removes last character (C++11) | void |
insert() |
str.insert(pos, s) |
Inserts string at position pos | string& |
erase() |
str.erase(pos, len) |
Erases characters | string& |
replace() |
str.replace(pos, len, s) |
Replaces portion of string | string& |
clear() |
str.clear() |
Clears the string | void |
swap() |
str1.swap(str2) |
Swaps contents with another string | void |
| String Operations | |||
c_str() |
str.c_str() |
Returns C-style string (const char*) | const char* |
data() |
str.data() |
Returns pointer to character array | const char* |
copy() |
str.copy(buf, len, pos) |
Copies characters to char array | size_t |
substr() |
str.substr(pos, len) |
Returns substring | string |
| Search Functions | |||
find() |
str.find(s, pos) |
Find content in string | size_t |
rfind() |
str.rfind(s, pos) |
Find last occurrence | size_t |
find_first_of() |
str.find_first_of(s, pos) |
Find character from set | size_t |
find_last_of() |
str.find_last_of(s, pos) |
Find last character from set | size_t |
find_first_not_of() |
str.find_first_not_of(s, pos) |
Find character not in set | size_t |
find_last_not_of() |
str.find_last_not_of(s, pos) |
Find last character not in set | size_t |
| Comparison Functions | |||
compare() |
str.compare(s) |
Compares two strings | int |
operator== |
str1 == str2 |
Equality operator | bool |
operator!= |
str1 != str2 |
Inequality operator | bool |
operator< |
str1 < str2 |
Less than operator | bool |
operator> |
str1 > str2 |
Greater than operator | bool |
| Iterators | |||
begin() |
str.begin() |
Returns iterator to beginning | iterator |
end() |
str.end() |
Returns iterator to end | iterator |
rbegin() |
str.rbegin() |
Returns reverse iterator | reverse_iterator |
rend() |
str.rend() |
Returns reverse iterator end | reverse_iterator |
cbegin() |
str.cbegin() |
Returns const iterator (C++11) | const_iterator |
cend() |
str.cend() |
Returns const iterator end (C++11) | const_iterator |
1. String Creation and Initialization
C++ strings can be created and initialized in multiple ways. Understanding these methods is essential for effective string handling.
#include <iostream>
#include <string>
using namespace std;
int main() {
// Method 1: Empty string
string str1;
cout << "Empty string: '" << str1 << "' Length: " << str1.length() << endl;
// Method 2: From C-string
string str2 = "Hello, World!";
string str3("C++ Programming");
cout << "str2: " << str2 << endl;
cout << "str3: " << str3 << endl;
// Method 3: From another string (copy)
string str4 = str2;
string str5(str3);
cout << "str4 (copy of str2): " << str4 << endl;
cout << "str5 (copy of str3): " << str5 << endl;
// Method 4: Repeat character
string str6(10, '*'); // "**********"
string str7(5, 'A'); // "AAAAA"
cout << "str6: " << str6 << endl;
cout << "str7: " << str7 << endl;
// Method 5: Substring of another string
string str8 = "Hello, World!";
string str9(str8, 7, 5); // "World" (start at 7, length 5)
cout << "str9 (substring): " << str9 << endl;
// Method 6: From part of C-string
string str10("Programming", 4); // "Prog" (first 4 chars)
cout << "str10: " << str10 << endl;
// Method 7: Using assignment operator
string str11;
str11 = "Assigned string";
cout << "str11: " << str11 << endl;
// Method 8: Using initializer list (C++11)
string str12{'H', 'e', 'l', 'l', 'o'};
cout << "str12 (initializer list): " << str12 << endl;
// Method 9: Move constructor (C++11)
string str13 = move(str11); // str11 becomes empty
cout << "str13 (moved from str11): " << str13 << endl;
cout << "str11 after move: '" << str11 << "'" << endl;
// Method 10: Using string literals (C++14)
using namespace std::string_literals;
string str14 = "Modern C++"s; // s suffix creates std::string
auto str15 = "Auto deduction"s; // auto deduces std::string
cout << "str14: " << str14 << endl;
cout << "str15: " << str15 << endl;
return 0;
}
Initialization Cheat Sheet
string s1; // Empty
string s2 = "text"; // From literal
string s3("text"); // Constructor
string s4 = s2; // Copy
string s5(5, 'x'); // Repeat char
string s6(s2, 1, 3); // Substring
string s7("text", 2); // First n chars
string s8{'a', 'b', 'c'}; // Initializer list
auto s9 = "text"s; // Literal suffix (C++14)
2. String Manipulation Functions
C++ provides numerous functions to modify string content. These functions allow you to append, insert, erase, replace, and transform strings.
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;
int main() {
string str = "Hello";
// 1. append() - Add to the end
str.append(" World");
cout << "After append: " << str << endl; // "Hello World"
// 2. Using += operator (concatenation)
str += "!";
cout << "After +=: " << str << endl; // "Hello World!"
// 3. insert() - Insert at position
str.insert(6, "Beautiful ");
cout << "After insert: " << str << endl; // "Hello Beautiful World!"
// 4. erase() - Remove characters
str.erase(6, 10); // Remove "Beautiful "
cout << "After erase: " << str << endl; // "Hello World!"
// 5. replace() - Replace portion
str.replace(6, 5, "C++"); // Replace "World" with "C++"
cout << "After replace: " << str << endl; // "Hello C++!"
// 6. push_back() and pop_back()
str.push_back('?');
cout << "After push_back: " << str << endl; // "Hello C++!?"
str.pop_back();
cout << "After pop_back: " << str << endl; // "Hello C++!"
// 7. clear() - Empty the string
string temp = "Temporary";
cout << "Before clear: '" << temp << "'" << endl;
temp.clear();
cout << "After clear: '" << temp << "'" << endl;
// 8. resize() - Change size
string resizeStr = "Hello";
resizeStr.resize(10, '!'); // Extend with '!'
cout << "After resize(10, '!'): '" << resizeStr << "'" << endl;
resizeStr.resize(3); // Shrink to first 3 chars
cout << "After resize(3): '" << resizeStr << "'" << endl;
// 9. swap() - Exchange contents
string a = "First";
string b = "Second";
cout << "Before swap - a: " << a << ", b: " << b << endl;
a.swap(b);
cout << "After swap - a: " << a << ", b: " << b << endl;
// 10. assign() - Assign new value
string assignStr;
assignStr.assign("New String");
cout << "After assign: " << assignStr << endl;
assignStr.assign(5, 'X');
cout << "After assign(5, 'X'): " << assignStr << endl;
// 11. Using STL algorithms with strings
string algorithmStr = "Hello World";
// Convert to uppercase
transform(algorithmStr.begin(), algorithmStr.end(),
algorithmStr.begin(), ::toupper);
cout << "Uppercase: " << algorithmStr << endl;
// Convert to lowercase
transform(algorithmStr.begin(), algorithmStr.end(),
algorithmStr.begin(), ::tolower);
cout << "Lowercase: " << algorithmStr << endl;
// Reverse the string
reverse(algorithmStr.begin(), algorithmStr.end());
cout << "Reversed: " << algorithmStr << endl;
// 12. Building strings efficiently
string builder;
builder.reserve(50); // Pre-allocate memory
for (int i = 0; i < 10; i++) {
builder.append("Item ").append(to_string(i)).append(", ");
}
cout << "Built string: " << builder << endl;
return 0;
}
reserve() before building large strings with multiple append operations. This reduces memory reallocations and improves performance significantly.
3. String Search and Find Operations
C++ provides powerful search functions to find substrings, characters, and patterns within strings. These functions return the position or string::npos if not found.
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
string text = "The quick brown fox jumps over the lazy dog";
// 1. find() - Find substring
size_t pos = text.find("fox");
if (pos != string::npos) {
cout << "'fox' found at position: " << pos << endl;
} else {
cout << "'fox' not found" << endl;
}
// 2. find() with starting position
pos = text.find("the", 10); // Start searching from position 10
cout << "'the' after position 10 found at: " << pos << endl;
// 3. rfind() - Find last occurrence
pos = text.rfind("the");
cout << "Last 'the' found at: " << pos << endl;
// 4. find_first_of() - Find any character from set
string vowels = "aeiouAEIOU";
pos = text.find_first_of(vowels);
cout << "First vowel at position: " << pos
<< " (character: " << text[pos] << ")" << endl;
// 5. find_last_of() - Find last character from set
pos = text.find_last_of(vowels);
cout << "Last vowel at position: " << pos
<< " (character: " << text[pos] << ")" << endl;
// 6. find_first_not_of() - Find character not in set
string alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ";
pos = text.find_first_not_of(alphabet);
if (pos != string::npos) {
cout << "First non-alphabetic character at: " << pos
<< " (character: " << text[pos] << ")" << endl;
}
// 7. find_last_not_of() - Find last character not in set
pos = text.find_last_not_of(alphabet);
if (pos != string::npos) {
cout << "Last non-alphabetic character at: " << pos
<< " (character: " << text[pos] << ")" << endl;
}
// 8. Practical example: Count occurrences
string sentence = "to be or not to be, that is the question";
string word = "be";
int count = 0;
size_t start = 0;
while ((start = sentence.find(word, start)) != string::npos) {
count++;
start += word.length(); // Move past this occurrence
}
cout << "Word '" << word << "' occurs " << count << " times" << endl;
// 9. Extract all words using find_first_of and find_first_not_of
string data = "apple,banana,cherry,date,elderberry";
cout << "\nExtracting words from: " << data << endl;
size_t commaPos = 0;
size_t nextComma = 0;
int wordNum = 1;
while ((nextComma = data.find(',', commaPos)) != string::npos) {
string word = data.substr(commaPos, nextComma - commaPos);
cout << "Word " << wordNum++ << ": " << word << endl;
commaPos = nextComma + 1;
}
// Last word
string lastWord = data.substr(commaPos);
cout << "Word " << wordNum << ": " << lastWord << endl;
// 10. Find and replace all occurrences
string replaceText = "I like cats. Cats are nice. Cats are cute.";
string searchStr = "Cats";
string replaceStr = "Dogs";
cout << "\nBefore replace: " << replaceText << endl;
size_t replacePos = 0;
while ((replacePos = replaceText.find(searchStr, replacePos)) != string::npos) {
replaceText.replace(replacePos, searchStr.length(), replaceStr);
replacePos += replaceStr.length(); // Move past replacement
}
cout << "After replace: " << replaceText << endl;
// 11. Checking if string starts/ends with substring (C++20 alternative)
string url = "https://www.example.com";
// Check if starts with "https://"
if (url.find("https://") == 0) {
cout << "\nURL uses HTTPS" << endl;
}
// Check if ends with ".com"
if (url.rfind(".com") == url.length() - 4) {
cout << "URL ends with .com" << endl;
}
// 12. Case-insensitive search (using transform)
string mixedCase = "Hello World";
string search = "hello";
string mixedLower = mixedCase;
string searchLower = search;
transform(mixedLower.begin(), mixedLower.end(), mixedLower.begin(), ::tolower);
transform(searchLower.begin(), searchLower.end(), searchLower.begin(), ::tolower);
if (mixedLower.find(searchLower) != string::npos) {
cout << "\nCase-insensitive search: Found '" << search << "' in '" << mixedCase << "'" << endl;
}
return 0;
}
- All find functions return
size_tposition if found - If not found, they return
string::npos string::nposis a static constant of typesize_twith value -1- Always check for
string::nposbefore using the result - Positions are zero-indexed
4. String Comparison Functions
C++ provides multiple ways to compare strings, including relational operators and the compare() member function for more detailed comparisons.
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;
// Function for case-insensitive comparison
bool caseInsensitiveCompare(const string& a, const string& b) {
if (a.length() != b.length()) return false;
for (size_t i = 0; i < a.length(); i++) {
if (tolower(a[i]) != tolower(b[i])) return false;
}
return true;
}
int main() {
string str1 = "apple";
string str2 = "banana";
string str3 = "Apple";
string str4 = "apple";
// 1. Using relational operators
cout << "Using relational operators:" << endl;
cout << str1 << " == " << str4 << " : " << (str1 == str4) << endl;
cout << str1 << " != " << str2 << " : " << (str1 != str2) << endl;
cout << str1 << " < " << str2 << " : " << (str1 < str2) << endl;
cout << str2 << " > " << str1 << " : " << (str2 > str1) << endl;
cout << str1 << " <= " << str4 << " : " << (str1 <= str4) << endl;
cout << str1 << " >= " << str4 << " : " << (str1 >= str4) << endl;
// 2. Using compare() member function
cout << "\nUsing compare() function:" << endl;
// compare() returns:
// 0 : strings are equal
// <0 : first string is less than second (lexicographically)
// >0 : first string is greater than second
int result = str1.compare(str2);
cout << str1 << ".compare(" << str2 << ") = " << result
<< " (apple < banana)" << endl;
result = str2.compare(str1);
cout << str2 << ".compare(" << str1 << ") = " << result
<< " (banana > apple)" << endl;
result = str1.compare(str4);
cout << str1 << ".compare(" << str4 << ") = " << result
<< " (apple == apple)" << endl;
// 3. compare() with substring comparison
string longStr = "Hello World Programming";
string searchStr = "World";
// Compare part of longStr with searchStr
result = longStr.compare(6, 5, searchStr); // Compare 5 chars from position 6
cout << "\nSubstring comparison: " << longStr << ".compare(6, 5, \"World\") = "
<< result << endl;
// 4. compare() with part of another string
string strA = "apple pie";
string strB = "apple tart";
// Compare first 5 chars of both strings
result = strA.compare(0, 5, strB, 0, 5);
cout << "\nPartial comparison: \"" << strA << "\".compare(0, 5, \""
<< strB << "\", 0, 5) = " << result << endl;
// 5. Case-sensitive vs case-insensitive comparison
cout << "\nCase sensitivity:" << endl;
cout << "\"apple\" == \"Apple\" : " << (str1 == str3) << " (case-sensitive)" << endl;
cout << "caseInsensitiveCompare(\"apple\", \"Apple\") : "
<< caseInsensitiveCompare(str1, str3) << " (case-insensitive)" << endl;
// 6. Lexicographical comparison examples
cout << "\nLexicographical comparisons:" << endl;
vector<string> words = {"zebra", "apple", "banana", "cherry", "date"};
sort(words.begin(), words.end());
cout << "Sorted words: ";
for (const auto& word : words) {
cout << word << " ";
}
cout << endl;
// 7. Numeric string comparison (potential pitfall)
string num1 = "100";
string num2 = "20";
cout << "\nNumeric string comparison (lexicographical):" << endl;
cout << "\"" << num1 << "\" < \"" << num2 << "\" : " << (num1 < num2) << endl;
cout << "Note: '1' comes before '2' alphabetically, so \"100\" < \"20\"" << endl;
// 8. Practical example: Sorting strings with custom comparator
vector<string> names = {"John", "mary", "Alice", "bob", "Zach"};
cout << "\nOriginal names: ";
for (const auto& name : names) cout << name << " ";
// Sort case-insensitively
sort(names.begin(), names.end(), [](const string& a, const string& b) {
string aLower = a, bLower = b;
transform(aLower.begin(), aLower.end(), aLower.begin(), ::tolower);
transform(bLower.begin(), bLower.end(), bLower.begin(), ::tolower);
return aLower < bLower;
});
cout << "\nCase-insensitive sorted: ";
for (const auto& name : names) cout << name << " ";
cout << endl;
// 9. Using compare() for switch-like behavior
string command = "DELETE";
// Convert to uppercase for case-insensitive comparison
string cmdUpper = command;
transform(cmdUpper.begin(), cmdUpper.end(), cmdUpper.begin(), ::toupper);
if (cmdUpper.compare("CREATE") == 0) {
cout << "\nExecuting CREATE command" << endl;
} else if (cmdUpper.compare("READ") == 0) {
cout << "\nExecuting READ command" << endl;
} else if (cmdUpper.compare("UPDATE") == 0) {
cout << "\nExecuting UPDATE command" << endl;
} else if (cmdUpper.compare("DELETE") == 0) {
cout << "\nExecuting DELETE command" << endl;
} else {
cout << "\nUnknown command" << endl;
}
return 0;
}
"100" < "20" returns true because '1' comes before '2' in ASCII. Convert to numbers for numerical comparison.
5. String Conversion and Advanced Operations
C++ strings can be converted to other types and combined with other C++ features for powerful text processing.
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cctype>
#include <locale> // For std::isspace
using namespace std;
int main() {
// 1. Converting numbers to strings
cout << "=== Number to String Conversion ===" << endl;
// Using to_string() (C++11)
int num = 42;
double pi = 3.14159;
string strNum = to_string(num);
string strPi = to_string(pi);
cout << "Integer to string: " << strNum << endl;
cout << "Double to string: " << strPi << endl;
// Using stringstream
stringstream ss;
ss << fixed << setprecision(2) << pi;
string formattedPi = ss.str();
cout << "Formatted pi: " << formattedPi << endl;
// 2. Converting strings to numbers
cout << "\n=== String to Number Conversion ===" << endl;
string strInt = "123";
string strFloat = "45.67";
int convertedInt = stoi(strInt);
float convertedFloat = stof(strFloat);
double convertedDouble = stod(strFloat);
cout << "String to int: " << convertedInt << endl;
cout << "String to float: " << convertedFloat << endl;
cout << "String to double: " << convertedDouble << endl;
// Handling invalid conversions
try {
string invalid = "123abc";
int value = stoi(invalid);
cout << "Parsed: " << value << endl;
} catch (const invalid_argument& e) {
cout << "Invalid argument: " << e.what() << endl;
}
// Using stoi with size_t parameter
string mixed = "123abc";
size_t pos;
int parsed = stoi(mixed, &pos);
cout << "Parsed number: " << parsed << ", stopped at position: " << pos << endl;
// 3. String stream operations
cout << "\n=== String Stream Operations ===" << endl;
// Parsing CSV data
string csv = "John,Doe,30,Engineer";
stringstream csvStream(csv);
vector<string> fields;
string field;
while (getline(csvStream, field, ',')) {
fields.push_back(field);
}
cout << "CSV fields: ";
for (const auto& f : fields) {
cout << "[" << f << "] ";
}
cout << endl;
// Building strings with stringstream
stringstream builder;
builder << "Name: " << "John" << ", Age: " << 30
<< ", Salary: $" << fixed << setprecision(2) << 75000.50;
cout << "Built string: " << builder.str() << endl;
// 4. String trimming functions
cout << "\n=== String Trimming ===" << endl;
// Left trim
auto ltrim = [](string& s) {
s.erase(s.begin(), find_if(s.begin(), s.end(), [](unsigned char ch) {
return !isspace(ch);
}));
};
// Right trim
auto rtrim = [](string& s) {
s.erase(find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
return !isspace(ch);
}).base(), s.end());
};
// Trim both sides
auto trim = [&](string& s) {
ltrim(s);
rtrim(s);
};
string untrimmed = " Hello World! ";
cout << "Original: '" << untrimmed << "'" << endl;
trim(untrimmed);
cout << "Trimmed: '" << untrimmed << "'" << endl;
// 5. String splitting
cout << "\n=== String Splitting ===" << endl;
auto split = [](const string& s, char delimiter) -> vector<string> {
vector<string> tokens;
stringstream tokenStream(s);
string token;
while (getline(tokenStream, token, delimiter)) {
tokens.push_back(token);
}
return tokens;
};
string sentence = "The quick brown fox jumps over the lazy dog";
vector<string> words = split(sentence, ' ');
cout << "Split words: ";
for (const auto& word : words) {
cout << "[" << word << "] ";
}
cout << endl;
// 6. String joining
cout << "\n=== String Joining ===" << endl;
auto join = [](const vector<string>& parts, const string& delimiter) -> string {
if (parts.empty()) return "";
string result = parts[0];
for (size_t i = 1; i < parts.size(); i++) {
result += delimiter + parts[i];
}
return result;
};
vector<string> items = {"Apple", "Banana", "Cherry", "Date"};
string joined = join(items, ", ");
cout << "Joined: " << joined << endl;
// 7. String case conversion
cout << "\n=== Case Conversion ===" << endl;
auto toUpper = [](string s) -> string {
transform(s.begin(), s.end(), s.begin(), ::toupper);
return s;
};
auto toLower = [](string s) -> string {
transform(s.begin(), s.end(), s.begin(), ::tolower);
return s;
};
string mixedCase = "Hello World";
cout << "Original: " << mixedCase << endl;
cout << "Uppercase: " << toUpper(mixedCase) << endl;
cout << "Lowercase: " << toLower(mixedCase) << endl;
// 8. Checking string properties
cout << "\n=== String Property Checks ===" << endl;
auto isNumeric = [](const string& s) -> bool {
if (s.empty()) return false;
for (char c : s) {
if (!isdigit(c)) return false;
}
return true;
};
auto isAlpha = [](const string& s) -> bool {
if (s.empty()) return false;
for (char c : s) {
if (!isalpha(c)) return false;
}
return true;
};
string test1 = "12345";
string test2 = "Hello";
string test3 = "Hello123";
cout << "'" << test1 << "' is numeric: " << isNumeric(test1) << endl;
cout << "'" << test2 << "' is alphabetic: " << isAlpha(test2) << endl;
cout << "'" << test3 << "' is alphabetic: " << isAlpha(test3) << endl;
// 9. String encoding and special characters
cout << "\n=== Special Characters and Encoding ===" << endl;
// Raw string literals (C++11)
string rawString = R"(This is a "raw" string\nNo escape sequences needed!)";
cout << "Raw string: " << rawString << endl;
// Unicode strings (C++11)
string unicodeStr = u8"Hello 世界"; // UTF-8 encoded
cout << "Unicode string: " << unicodeStr << endl;
// 10. Performance considerations
cout << "\n=== Performance Tips ===" << endl;
// Using reserve() for building strings
string largeString;
largeString.reserve(1000); // Pre-allocate memory
for (int i = 0; i < 100; i++) {
largeString.append("Item ").append(to_string(i)).append("\n");
}
cout << "Built large string with " << largeString.length() << " characters" << endl;
cout << "Capacity: " << largeString.capacity() << endl;
// Using shrink_to_fit() to reduce memory usage
largeString.shrink_to_fit();
cout << "After shrink_to_fit, capacity: " << largeString.capacity() << endl;
return 0;
}
- Use
reserve()before building large strings with multiple append operations - Use
shrink_to_fit()after building to minimize memory usage - Pass strings by
const referenceto avoid unnecessary copies - Use
string_view(C++17) for read-only string parameters - Avoid repeated concatenation with
+in loops
6. Best Practices and Common Mistakes
Best Practices
- Use
std::stringinstead of C-style strings - Pass strings by
const std::string&for read-only access - Use
reserve()when building large strings - Prefer
find()over manual character-by-character search - Use
empty()instead ofsize() == 0 - Handle
string::nposproperly in search operations - Use
std::string_view(C++17) for read-only parameters
Common Mistakes
- Not checking
string::nposafterfind() - Using
[]operator without bounds checking - Forgetting to
#include <string> - Memory leaks with
c_str()pointers - Inefficient string concatenation in loops
- Case-sensitive comparison when case-insensitive is needed
- Assuming ASCII encoding for international text
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
cout << "=== BAD PRACTICES ===" << endl;
// BAD 1: Not checking bounds
string str = "Hello";
// char c = str[10]; // UNDEFINED BEHAVIOR!
// cout << "Bad access: " << c << endl;
// BAD 2: Inefficient concatenation in loop
string result;
for (int i = 0; i < 100; i++) {
result += "data"; // Creates many temporary strings
}
// BAD 3: Not checking find() result
string text = "Hello World";
size_t pos = text.find("Mars");
// string sub = text.substr(pos, 5); // CRASH if pos == string::npos
// BAD 4: Using C-style strings unnecessarily
char cstr[100];
// strcpy(cstr, text.c_str()); // Risk of buffer overflow
cout << "\n=== GOOD PRACTICES ===" << endl;
// GOOD 1: Safe bounds checking
if (str.length() > 10) {
char c = str[10];
cout << "Safe access: " << c << endl;
} else {
cout << "Index out of bounds" << endl;
}
// Or use at() which throws exception
try {
char c = str.at(10);
} catch (const out_of_range& e) {
cout << "Caught exception: " << e.what() << endl;
}
// GOOD 2: Efficient string building
string efficientResult;
efficientResult.reserve(500); // Pre-allocate memory
for (int i = 0; i < 100; i++) {
efficientResult.append("data");
}
cout << "Efficiently built string of length: " << efficientResult.length() << endl;
// GOOD 3: Proper find() checking
pos = text.find("Mars");
if (pos != string::npos) {
string sub = text.substr(pos, 5);
cout << "Found substring: " << sub << endl;
} else {
cout << "Substring not found" << endl;
}
// GOOD 4: Using string functions instead of manual loops
string data = "Hello,World,OpenAI,ChatGPT";
// GOOD: Using find() and substr()
vector<string> tokens;
size_t start = 0, end = 0;
while ((end = data.find(',', start)) != string::npos) {
tokens.push_back(data.substr(start, end - start));
start = end + 1;
}
tokens.push_back(data.substr(start));
cout << "Parsed tokens: ";
for (const auto& token : tokens) {
cout << "[" << token << "] ";
}
cout << endl;
// GOOD 5: Using modern C++ features
// C++17: string_view for read-only parameters
#if __cplusplus >= 201703L
cout << "\nC++17 string_view example (compiled with C++17 or later)" << endl;
#endif
// GOOD 6: Proper error handling for conversions
string numberStr = "123abc";
try {
int value = stoi(numberStr);
cout << "Converted: " << value << endl;
} catch (const invalid_argument& e) {
cout << "Invalid number format: " << numberStr << endl;
} catch (const out_of_range& e) {
cout << "Number out of range: " << numberStr << endl;
}
// GOOD 7: Using empty() for emptiness check
string emptyStr;
if (emptyStr.empty()) {
cout << "String is empty (using empty())" << endl;
}
// BETTER than: if (emptyStr.size() == 0)
// GOOD 8: Avoiding dangling pointers from c_str()
string temp = "Temporary";
const char* ptr = temp.c_str();
temp = "Modified"; // ptr may become invalid
// SAFE: Use c_str() immediately or store the string
cout << "Current string: " << temp << endl;
cout << "Current c_str(): " << temp.c_str() << endl;
return 0;
}