How to remove all the occurrences of a char in c++ string
Categories:
Efficiently Removing All Occurrences of a Character from a C++ String

Learn various C++ Standard Library (STL) techniques to effectively remove all instances of a specific character from a string, optimizing for performance and readability.
Removing specific characters from a string is a common task in C++ programming. Whether you're cleaning user input, parsing data, or preparing strings for display, the C++ Standard Library offers several powerful and efficient ways to achieve this. This article explores different approaches, focusing on std::remove, std::erase, and std::remove_if in conjunction with std::string::erase, providing practical examples and performance considerations.
Understanding the Erase-Remove Idiom
The 'erase-remove idiom' is a fundamental pattern in C++ for removing elements from containers that do not automatically resize, such as std::vector or std::string. The std::remove algorithm does not actually remove elements from the container; instead, it rearranges them, moving all elements not to be removed to the beginning of the range and returning an iterator to the new logical end of the range. The elements between this new logical end and the physical end of the container are left in an unspecified but valid state. To truly remove these elements and resize the container, you must then call the container's erase method with the iterators returned by std::remove.
flowchart TD
A[Original String] --> B{std::remove(begin, end, char_to_remove)}
B --> C[String with unwanted chars moved to end]
C --> D{std::string::erase(new_end, old_end)}
D --> E[Final String without unwanted chars]
style A fill:#f9f,stroke:#333,stroke-width:2px
style E fill:#bbf,stroke:#333,stroke-width:2pxThe Erase-Remove Idiom Workflow
Method 1: Using std::remove and std::string::erase
This is the most idiomatic and generally preferred way to remove elements from a std::string or other sequence containers. It leverages the std::remove algorithm to shift elements and then std::string::erase to physically remove the unwanted characters and resize the string.
#include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string str = "Hello, World! This is a test.";
char charToRemove = 'o';
// Use std::remove to move all 'o's to the end
// and get an iterator to the new logical end.
str.erase(std::remove(str.begin(), str.end(), charToRemove), str.end());
std::cout << "String after removing '" << charToRemove << "': " << str << std::endl;
charToRemove = ' '; // Remove spaces
str.erase(std::remove(str.begin(), str.end(), charToRemove), str.end());
std::cout << "String after removing spaces: " << str << std::endl;
return 0;
}
Removing characters using std::remove and std::string::erase
std::remove algorithm is highly efficient as it performs a single pass over the range. The subsequent std::string::erase operation then handles the actual memory manipulation, which is also optimized for std::string.Method 2: Using std::remove_if with a Lambda or Predicate
If you need to remove characters based on a more complex condition than a simple equality check, std::remove_if is the ideal choice. It works similarly to std::remove but takes a unary predicate (a function or lambda that returns true for elements to be removed) as its third argument.
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype> // For ispunct, isspace, etc.
int main() {
std::string str = "Hello, World! 123 This is a test.";
// Remove all punctuation characters
str.erase(std::remove_if(str.begin(), str.end(),
[](char c) { return std::ispunct(static_cast<unsigned char>(c)); }),
str.end());
std::cout << "After removing punctuation: " << str << std::endl;
// Remove all digits
str.erase(std::remove_if(str.begin(), str.end(),
[](char c) { return std::isdigit(static_cast<unsigned char>(c)); }),
str.end());
std::cout << "After removing digits: " << str << std::endl;
return 0;
}
Removing characters using std::remove_if with a lambda
std::ispunct, std::isdigit, etc., from <cctype>, it's crucial to cast the char argument to unsigned char. This prevents potential undefined behavior if the char is negative (e.g., for extended ASCII characters) and not representable as an unsigned char.Method 3: Iterating and Erasing (Less Efficient)
While possible, iterating through a string and erasing characters one by one is generally less efficient than the erase-remove idiom, especially for large strings or frequent removals. Each std::string::erase(iterator) operation can potentially shift all subsequent characters, leading to a quadratic time complexity in the worst case (e.g., removing every character).
#include <iostream>
#include <string>
int main() {
std::string str = "Programming is fun!";
char charToRemove = 'g';
for (auto it = str.begin(); it != str.end(); ) {
if (*it == charToRemove) {
it = str.erase(it); // erase returns an iterator to the next element
} else {
++it;
}
}
std::cout << "String after removing '" << charToRemove << "': " << str << std::endl;
return 0;
}
Removing characters by iterating and erasing (generally not recommended)
std::remove cannot be easily adapted. However, for general character removal, prefer the erase-remove idiom.