Replace character in string with another?

17 Sep 2012

I want to replace a character in this array item

pFields[1]

Lets say the array item contains "Hello<World"

I want to replace the arrow with a space so it ends up looking like this

"Hello World"

How would i go about doing that?

Gosh c++ is crazy >.<

18 Sep 2012

Anyone home?

18 Sep 2012
27 Aug 2014

Ok i've just come back to this project however i can't really find anything that will replace the "<" in a string...

Is there any chance someone can help by putting some example code bellow?

if (strcmp("text", pFields[0]) == 0) { tft.DrawString(pFields[1], atoi(pFields[2]), atoi(pFields[3]), atoi(pFields[4]), uint16_t(tft.Colour565(atoi(pFields[5]), atoi(pFields[6]), atoi(pFields[7])))); }

pFields[1] returns nothing if there is a space in the string however i'm unsure why. It may have made an array of the strings like such

pFields[1][0] and pFields[1][1] for the second word

Confusing stuff :\

I need to change a delimited char in the string "hello<you<weirdos" to "hello you weirdos" in pFields[1]

27 Aug 2014

Hey, from the code supplied I can't really tell what you are doing, where does pFields come from?

A string in c is just a char array with a null when the string stops which may be anywhere in the array. assuming what is in pFields is a string we can change a character simply by setting it:

pFields[1][1] = 'n';

this would change the second character of the string at pFeilds[1] to a n, again assuming the string in more then 2 characters long.

so with this information, all we have to do is loop over each character in the array checking if its the token you want to replace, and if it is replace it, until we find a null(0) then stop.

int i = 0;  //set i to 0
while(pFields[1][i] != 0){ //check if we reached the end of the string (current char is 0)
    if(pFields[1][i] == '<'){ //check if the character is the token to be replaced
        pFields[1][i] = ' '; //if it is replace it
    }
    i++; //increment the index variable
}

Quote:

pFields[1] returns nothing if there is a space in the string

not sure what you mean by that, if pFields[1] is 0, as pFeilds is an array of pointers to strings, it means that there is no string.

hope this helps and I didn't totally misunderstand what your question was,

28 Aug 2014

thanks that helped allot! :) finally.

28 Aug 2014

The code I gave you will work on any string to replace characters, not sure what your last reply was about, if you supply the code you are using to receive and separate the comma separated values string over serial maybe i can help more.

you edited you reply before i posted mine so never mind ;)

29 Aug 2014

Below snippet solution with STL, its, a little cleaner but still slower that native while(character++) loop:

#include <algorithm>    // std::replace

int main(int argc, char* argv[])
{
    char str[] = "Hello<World!";
    char* begin = str;   // Points to string beggining
    char* end = str+ strlen(str); // Points to string end
    std::replace(begin, end, '<', ' ');
    return 0;
}

// Shorter version:
char str[] = "Hello<World!";
std::replace(str, str + strlen(str), '<', ' ');

Note: if you define 'string' like below you can have memory access violation:

char* str= "Hello<World!";
29 Aug 2014

Indeed using the STL is very much the right thing to do when performance isn't a priority, The solution I gave used the variables that he had available and was simplified to make it easy to understand. I tend to try and use std::string when I can as making a bad mistake, (infinite loop buffer overflows), is much harder and it has many useful methods.

29 Aug 2014

Hey Matthew, just had a look at the library you released with my code snippet, and I'd like to show you an example implementation with the STL to show you that C++ doesn't have to be so awkward with strings.

    //serial input buffer example;
    char buffer[] =  "text,hello world,20,10,2,255,255,255";
    char delimiter = ',';
    
    std::stringstream ss(buffer);
    std::vector<std::string> result;
    while( ss.good() ) {
       std::string substr;
       std::getline( ss, substr, delimiter );
       result.push_back( substr );
    }
    
    //result now holds each part of the command
    
    if(result.size() > 0){
        //the command had at least 1 part
        if(result[0].compare("text") == 0){
            //the command was the text command
            pc.printf("TEXT COMMAND\r\n");
            if(result.size() == 8){
                //the command had the correct amount of arguments
                pc.printf("VALID\r\n");    
            } else {
                //invalid arguments
                pc.printf("INVALID\r\n");    
            }
        }    
    }

This requires 3 includes:

#include <string>
#include <vector>
#include <sstream>

Using this you shouldn't require the workaround of changing spaces to another character. It takes about 500us to parse, I haven't tested your implementation.

The Implementation I use in my GPS NMEA parser is:

    std::string raw_data( buffer);
    std::string  temp;
    while (raw_data.find(",", 0) != std::string::npos) {
        std::size_t  pos = raw_data.find(",", 0);
        temp = raw_data.substr(0, pos);
        raw_data.erase(0, pos + 1);
        if (temp.size() == 0) {
            temp = "0";
        }
        result.push_back(temp);
    }
    result.push_back(raw_data);

This will parse the same string in about 70us, but isnt as tidy. It also fills in 0's if there is no value between the commas. (an annoyance of the NMEA protocol)