Home > Software engineering >  Am replacing the first occurrence of a string, how can I replace all occurrences?
Am replacing the first occurrence of a string, how can I replace all occurrences?

Time:11-07

I have already bulid the basic structure by using the loop replace,In C , the str.replace is only to replace single string, however, in some cases, we need to replace all the same string, My code can compile successfully and can output to the screen, but it seems that it does not replace successfully.

Thanks in advance

here's my code:

#include <iostream>
#include <fstream>
#include <string>
int main(void)
{
    // initialize
    std::ofstream fout;
    std::ifstream fin;
    fout.open("cad.dat");
    fout <<  "C is a Computer Programming Language which is used worldwide, Everyone should learn how to use C" << std::endl;

    fin.open("cad.dat");
    std::string words;
    getline(fin,words);
    std::cout << words << std::endl;
 
    while(1)
    {
        std::string::size_type pos(0);
        if (pos = words.find("C") != std::string::npos && words[pos 1] != ' ') //the later one is used to detect the single word "C"
        {
            words.replace(pos, 1, "C  "); 
        }
        else
        {
            break;
        }
    }

    std::cout << words;
}

CodePudding user response:

You can simplify your program by just using regex as follows:

std::regex f("\\bC\\b");
words = std::regex_replace(words, f, "C  "); // replace "C" with "C  "

Then there is no need for a while loop as shown in the below program:


#include <iostream>
#include <fstream>
#include <regex>
#include <string>
int main(void)
{
    // initialize
    std::ofstream fout;
    std::ifstream fin;
    fout.open("cad.dat");
    fout <<  "C is a Computer Programming Language which is used worldwide, Everyone should learn how to use C" << std::endl;

    fin.open("cad.dat");
    std::string words;
    getline(fin,words);
    std::cout << words << std::endl;
 
    std::regex f("\\bC\\b");
    words = std::regex_replace(words, f, "C  "); // replace "C" with "C  "

    std::cout << words;
}

CodePudding user response:

You need to save pos and use it for the following find operations but you currently initialize it to 0 every iteration in the while loop.

You could replace the while while loop with this for example:

for(std::string::size_type pos = 0;
    (pos = words.find("C", pos)) != std::string::npos; // start find at pos
    pos  = 1)  // skip last found "C"
{
    if(pos   1 == words.size() || words[pos   1] == ' ')
        words.replace(pos, 1, "C  ");
}

Note: This will replace the C in words ending with C too, for example an acronym like C2C will become C2C . Also, a sentence ending with C. would not be handled. To handle these cases you could add a check for the character before the found C too and add punctuation to the check.

Example:

#include <cctype>   // isspace, ispunct
#include <iostream>
#include <string>

int main()
{
    std::string words = "C Computer C2C C. I like C, because it's C";
    std::cout << words << '\n';

    // a lambda to check for space or punctuation characters:
    auto checker = [](unsigned char ch) {
        return std::isspace(ch) || std::ispunct(ch);
    };

    for(std::string::size_type pos = 0;
        (pos = words.find("C", pos)) != std::string::npos;
        pos  = 1)
    {
        if( (pos == 0 || checker(words[pos - 1])) &&
            (pos   1 == words.size() || checker(words[pos   1]))
        ) {
            words.replace(pos, 1, "C  ");
        }
    }

    std::cout << words << '\n';
}

Output:

C Computer C2C C. I like C, because it's C
C   Computer C2C C  . I like C  , because it's C  
  • Related