HOWTO · C++
How to Trim a String in C++
Trim selected characters from the left, right, or both ends of a C++ string with find_first_not_of, find_last_not_of, and erase.
On this page
Trimming removes selected characters from the beginning or end of a string. It does not remove matching characters from the middle. The standard string search functions let you define which characters count as trim characters; erase then removes the matching range. The examples below change the original std::string in place.
Choose which characters to trim
The argument to find_first_not_of and find_last_not_of is a set of individual characters. Each function searches for a character that is not in that set; the argument is not a substring or a pattern. For example, the set " ." means a literal space or period, in either order. It does not mean the two-character sequence space-period.
Choose the set to match your input. A literal space trims only spaces. A whitespace set can include spaces, tabs, and line breaks. These searches inspect char elements, so a byte-oriented trim set does not by itself identify every Unicode whitespace character in UTF-8 text.
Trim the left side with find_first_not_of and erase
Find the first character outside the trim set, then erase everything before it. This example removes spaces and periods from the left edge. It is a self-contained C++ program.
Run this example:
#include <iostream>
#include <string>
int main() {
std::string value = "...C++ guide...";
const std::string trim_chars = " .";
const std::string::size_type first = value.find_first_not_of(trim_chars);
value.erase(0, first);
std::cout << value << '\n';
}
C++ guide...
find_first_not_of returns the index of the first character outside the set. If every character belongs to the set, it returns std::string::npos; passing that position as the count to erase(0, ...) removes the whole string. The example therefore also handles a string made only of trim characters.
Trim the right side with find_last_not_of and erase
For the right edge, search backward for the last character outside the trim set. Erase the suffix that follows it. The position returned by find_last_not_of is an index, so add one to get the suffix’s starting position.
#include <iostream>
#include <string>
int main() {
std::string value = "C++ guide... ";
const std::string trim_chars = " .";
const std::string::size_type last = value.find_last_not_of(trim_chars);
if (last == std::string::npos) {
value.clear();
} else {
value.erase(last + 1);
}
std::cout << value << '\n';
}
C++ guide
The guard matters because find_last_not_of returns std::string::npos when no character is outside the set. Adding one to that sentinel would wrap the unsigned position value. Clearing the string handles an all-trim-character input directly.
Trim both sides and handle strings with no retained characters
To trim both edges, locate the first and last characters outside the set, then erase the suffix and prefix. Check the first result before doing position arithmetic: if it is std::string::npos, the string has no retained characters. This also handles an empty input safely.
#include <iostream>
#include <string>
int main() {
std::string value = "...C++ guide...";
const std::string trim_chars = " .";
const std::string::size_type first = value.find_first_not_of(trim_chars);
if (first == std::string::npos) {
value.clear();
} else {
const std::string::size_type last = value.find_last_not_of(trim_chars);
value.erase(last + 1);
value.erase(0, first);
}
std::cout << value << '\n';
}
C++ guide
The erase calls mutate value; they do not create a trimmed copy. If you need to preserve the original, make a copy first and trim that copy. std::string::npos is the sentinel used for a search that finds no qualifying character, and must be checked before using it in index arithmetic.
Trim whitespace or another character set
The same approach works for whitespace by changing the set. For the six basic whitespace characters commonly represented in C and C++ character handling, use the characters space, tab, newline, carriage return, form feed, and vertical tab: " \t\n\r\f\v". This set is explicit and predictable for these byte values; it does not cover every Unicode whitespace character.
For example, use that string as trim_chars in either edge search above to remove those characters at the edges. Use a narrower set when the data format defines only spaces and tabs as padding. Trimming a set removes any of its individual characters at an edge, while collapsing whitespace inside a string is a different operation. A regular-expression replacement of whitespace runs can change interior spacing and still leave whitespace at the edges, so it is not a substitute for trimming.
If your project already uses Boost, its String Algorithms documentation describes an optional library route for trimming. Check the documentation for the Boost version used by your project. The standard-library examples above need no additional library.