Page 1 of 1

Replacing Strings in C++

Posted: Mon Apr 23, 2007 2:24 am
by pcmattman
I'm using the string class in a C++ program I'm writing to assist me in diagnosing network issues.

The problem is, I need to be able to handle newlines written into the console as '\n' (ie. '\\', 'n'). I need to be able to replace the string "\n" (which is two bytes) to '\n' (the one byte version), and make sure no remnants are left over.

I'm using VC++ 6.

Edit: never mind, I got it:

Code: Select all



				// search for newlines
				int lastf = 0;
				for( i = 0; i < dat.length(); i++ )
				{
					if( lastf != 0 )
					{
						lastf = dat.find( "\\n", lastf + 1 );
					}
					else
					{
						lastf = dat.find( "\\n", lastf );
					}

					if( lastf == -1 )
						break;
					else
					{
						dat.replace( lastf, 2, "\n" );
					}
				}

Posted: Mon Apr 23, 2007 3:25 am
by mystran
If you need to process more than one escape, I suggest you take the source string, and copy it to destination string one character at a time. Both strings can actually be the same, if you want to work in place. You keep separate index for each. While reading the source, if you hit a backslash, instead of just copying it, you advance the source-index only, looking at the next character to see what kind of escape it is, and then write the escaped special character instead of the two characters. This way you only have to go over the string once.

It's been too long since I used STL strings for anything, so I'll give an example in C:

Code: Select all

// replaces \n with newline, \e with escape, \b with backspace and \\ with \
// returns -1 and prints error if other escapes are encountered
int replace_escapes(char * dest, const char * src) {
   int si = 0, di = 0;
   while(src[si]) {
      if(src[si] == '\\') {
         switch(src[++si]) {
           case 'e': dest[di] = '\033'; break;
           case 'n': dest[di] = '\n'; break;
           case 'b': dest[di] = '\b'; break;
           case '\\': dest[di] = '\\'; break;
           default: fprintf(stderr, "invalid escape \\%c\n", src[si]); return -1;             
      } else {
           dest[di] = src[si];
      }
      ++si; ++di;
   }
}

Posted: Mon Apr 23, 2007 5:43 am
by Solar

Code: Select all

size_t pos = 0;
while ( ( pos = mystring.find( "\\n", pos ) ) != string::npos )
{
    mystring.replace( pos++, 2, "\n" );
}
Can probably be optimized further, but should suffice as example for how to do it with the STL.

Posted: Mon Apr 23, 2007 2:57 pm
by pcmattman
Hmmm... sounds good.

I'll have to write a str_replace() function to do the same thing with ny length string. Saves a lot of code space sometimes :D.