3

small question about C++ replace function. I'm parsing every line of text input line by line. Example of the text file:

SF27_34KJ
EEE_30888
KPD324222
4230_333

And I need to remove all the underscores on every line and replace it with a comma. When I try something like this:

mystring.replace(mystring.begin(), mystring.end(), '_', ',');

on every line - instead of "SF27,34KJ" I get 95x "," char. What could be wrong?

user1175307
  • 151
  • 1
  • 1
  • 13
  • http://stackoverflow.com/questions/2896600/how-to-replace-all-occurrences-of-a-character-in-string – Pragnesh Patel Jun 14 '12 at 15:44
  • 4
    You are confusing `std::replace` with `string.replace`. – P.P Jun 14 '12 at 15:45
  • 1
    Short explanation: `std::replace` replaces all occurrences of a string within another, whereas `string::replace` just replaces a substring in a specified location. – Eitan T Jun 14 '12 at 15:58

4 Answers4

6

Use std::replace():

std::replace(mystring.begin(), mystring.end(), '_', ',');
hmjd
  • 120,187
  • 20
  • 207
  • 252
1

basic_string::replace doesn't do what you think it does.

basic_string::replace(it_a, it_e, ... ) replaces all of the characters between it_a and it_e with whatever you specify, not just those that match something.

There are a hundred ways to do what you're trying to do, but the simplest is probably to use the std::replace from <algorithm>, which does do what you want:

std::replace(mystring.begin(), mystring.end(), '_', ',');

Another method is to use std::transform in conjunction with a functor. This has an advantage over std::replace in that you can perform multiple substitutions in a single pass.

Here is a C++03 functor that would do it:

struct ReplChars
{
    char operator()(char c) const
    {
        if( c == '_' )
            return ',';
        if( c == '*' )
            return '.';
        return c;
    }
};

...and the use of it:

std::transform(mystring.begin(), mystring.end(), mystring.begin(), ReplChars());

In C++11, this can be reduced by using a lambda instead of the functor:

std::transform(mystring.begin(), mystring.end(), mystring.begin(), [](char c)->char
{
    if( c == '_' )
        return ',';
    if( c == '*' )
        return '.';
    return c;
});
John Dibling
  • 99,718
  • 31
  • 186
  • 324
0

Looking here, there is no replace method which takes two iterators and then two characters. Considering the ascii value of '_' is 95, I'm guessing you're hitting this one instead:

string& replace ( iterator i1, iterator i2, size_t n2, char c );

So instead of replacing all instances of '_' with ',', instead you're replacing the string from begin() to end() with 95 ','s.

See here for how to replace occurrances in a string.

Community
  • 1
  • 1
N_A
  • 19,799
  • 4
  • 52
  • 98
0

This isn't exactly how replace works. Check out the api http://www.cplusplus.com/reference/string/string/replace/, you give iterators for the beginning and end along with a string to copy in, but the other argument is the maximum length of that section.

To get the functionality that you're going for, try finding a substring and replacing it (two calls). That's detailed here: Replace part of a string with another string .

Community
  • 1
  • 1
Cannoliopsida
  • 3,044
  • 5
  • 36
  • 61