What is the best way to replace characters in a string?
Specifically:
"This,Is A|Test" ----> "This_Is_A_Test"
I want to replace all commas, spaces, and "|" with underscores.
(I have access to Boost.)
What is the best way to replace characters in a string?
Specifically:
"This,Is A|Test" ----> "This_Is_A_Test"
I want to replace all commas, spaces, and "|" with underscores.
(I have access to Boost.)
As the other answers indicated, you can use the various replace
methods. However, these approaches have the downside of scanning the string multiple times (one time for each character). I would recommend rolling your own replace method, if you care about speed:
void beautify(std::string &s) {
int i;
for (i = 0; i < s.length(); ++i) {
switch (s[i]) {
case ' ':
case ',':
case '|':
s[i] = '_';
}
}
}
You could use the standard replace_if
algorithm, except the predicate is rather complicated (to be expressed inline with current C++ standard and no lambda).
You could write your own, or use is_any_of
from boost's string algorithms, so:
#include <algorithm>
#include <string>
#include <boost/algorithm/string/classification.hpp>
#include <iostream>
int main()
{
std::string s("This,Is A|Test");
std::replace_if(s.begin(), s.end(), boost::is_any_of(", |"), '_');
std::cout << s << '\n';
}
You could use the STL-Algorithm replace_if.
EDIT: As Space_C0wb0y said, replace_if
is definitely better. Here's some simpler sample code:
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
bool isBad(char c)
{
const string bad_chars = "|, ";
return (bad_chars.find(c) != string::npos);
}
int main()
{
string str = "This,Is A|Test";
// Replace!
replace_if(str.begin(),str.end(),isBad,'_');
cout<<str<<endl;
return 0;
}
OLD ANSWER:
Use std::replace with std::find_first_of
boost::replace_all(s, old, new);
The C++ Standard Library has access to these functions as well without using BOOST. Refer to the replace C++ Reference. Is this the best way ? I guess that's up to discussion. To replace multiple / different characters, you may have to call replace more than once.
#include <string>
string& replace( size_type index, size_type num, const string& str );
string& replace( size_type index1, size_type num1, const string& str, size_type index2, size_type num2 );
string& replace( size_type index, size_type num, const Char* str );
string& replace( size_type index, size_type num1, const Char* str, size_type num2 );
string& replace( size_type index, size_type num1, size_type num2, Char ch);
string& replace( iterator start, iterator end, const string& str );
string& replace( iterator start, iterator end, const Char* str );
string& replace( iterator start, iterator end, const Char* str, size_type num );
string& replace( iterator start, iterator end, size_type num, Char ch );
string& replace( iterator start, iterator end, input_iterator start2, input_iterator end2 );
Example program:
// replacing in a string
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string base="this is a test string.";
string str2="n example";
string str3="sample phrase";
string str4="useful.";
// function versions used in the same order as described above:
// Using positions: 0123456789*123456789*12345
string str=base; // "this is a test string."
str.replace(9,5,str2); // "this is an example string."
str.replace(19,6,str3,7,6); // "this is an example phrase."
str.replace(8,10,"just all",6); // "this is just a phrase."
str.replace(8,6,"a short"); // "this is a short phrase."
str.replace(22,1,3,'!'); // "this is a short phrase!!!"
// Using iterators: 0123456789*123456789*
string::iterator it = str.begin(); // ^
str.replace(it,str.end()-3,str3); // "sample phrase!!!"
str.replace(it,it+6,"replace it",7); // "replace phrase!!!"
it+=8; // ^
str.replace(it,it+6,"is cool"); // "replace is cool!!!"
str.replace(it+4,str.end()-4,4,'o'); // "replace is cooool!!!"
it+=3; // ^
str.replace(it,str.end(),str4.begin(),str4.end());
// "replace is useful."
cout << str << endl;
return 0;
}
I was writing this, when Space_C0wb0y posted his answer, which is the right answer for your question. This is a bit more complicated, but handles more possible replacements.
(sorry, not compiled/tested)
class MyReplacer
{
friend std::ostream& operator<<(std::ostream& os, const MyReplacer& Repl);
public:
MyReplacer(char c) : ch(c) {}
private:
char ch;
};
std::ostream& operator<<(std::ostream& os, const MyReplacer& Repl)
{
switch (Repl.ch)
{
case '|':
case ' ':
case ',': os << '_'; break;
default: os << Repl.ch;
}
return os;
}
std::ostringstream oss;
std::copy(str.begin(), str.end(), std::ostream_iterator<MyReplacer>(oss));
std::string result = oss.str();