什么是有效的方法来取代一个字符的所有出现与另一个字符在std::字符串?


当前回答

这个工作!我在书店应用程序中使用了类似的方法,其中库存存储在CSV(类似于.dat文件)中。但在单字符的情况下,意味着替换者只是一个单字符,例如'|',它必须在双引号"|"中,以避免抛出无效的转换const char。

#include <iostream>
#include <string>

using namespace std;

int main()
{
    int count = 0;  // for the number of occurences.
    // final hold variable of corrected word up to the npos=j
    string holdWord = "";
    // a temp var in order to replace 0 to new npos
    string holdTemp = "";
    // a csv for a an entry in a book store
    string holdLetter = "Big Java 7th Ed,Horstman,978-1118431115,99.85";

    // j = npos
    for (int j = 0; j < holdLetter.length(); j++) {

        if (holdLetter[j] == ',') {

            if ( count == 0 ) 
            {           
                holdWord = holdLetter.replace(j, 1, " | ");      
            }
            else {

                string holdTemp1 = holdLetter.replace(j, 1, " | ");

                // since replacement is three positions in length,
                // must replace new replacement's 0 to npos-3, with
                // the 0 to npos - 3 of the old replacement 
                holdTemp = holdTemp1.replace(0, j-3, holdWord, 0, j-3); 

                holdWord = "";

                holdWord = holdTemp;

            }
            holdTemp = "";
            count++;
        }
    } 
    cout << holdWord << endl;
    return 0;
}

// result:
Big Java 7th Ed | Horstman | 978-1118431115 | 99.85

我目前使用CentOS,所以我的编译器版本如下。c++版本(g++), c++ 98默认值:

g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

其他回答

如何替换任何字符串与任何字符串仅使用良好的旧C字符串函数?

char original[256]="First Line\nNext Line\n", dest[256]="";
char* replace_this = "\n"; // this is now a single character but could be any string
char* with_this = "\r\n"; // this is 2 characters but could be of any length

/* get the first token */
char* token = strtok(original, replace_this);

/* walk through other tokens */
while (token != NULL) {
    strcat(dest, token);
    strcat(dest, with_this);
    token = strtok(NULL, replace_this);
}

Dest现在应该有我们要找的东西了。

这是我滚动的一个解决方案,在最大的DRI精神。 它将在sHaystack中搜索sNeedle并将其替换为sReplace, nTimes如果不为0,否则所有的sNeedle发生。 它不会在替换的文本中再次搜索。

std::string str_replace(
    std::string sHaystack, std::string sNeedle, std::string sReplace, 
    size_t nTimes=0)
{
    size_t found = 0, pos = 0, c = 0;
    size_t len = sNeedle.size();
    size_t replen = sReplace.size();
    std::string input(sHaystack);

    do {
        found = input.find(sNeedle, pos);
        if (found == std::string::npos) {
            break;
        }
        input.replace(found, len, sReplace);
        pos = found + replen;
        ++c;
    } while(!nTimes || c < nTimes);

    return input;
}

想象一个大的二进制blob,其中所有0x00字节都应该被“\1\x30”取代,所有0x01字节都应该被“\1\x31”取代,因为传输协议不允许有0字节。

在以下情况下:

被替换的字符串和被替换的字符串长度不同, 要替换的字符串在源字符串和中多次出现 源字符串很大,

所提供的解决方案不能应用(因为它们只替换单个字符),或者存在性能问题,因为它们会多次调用string::replace,从而反复生成blob大小的副本。 (我不知道提升方案,也许从这个角度来看是可以的)

这个函数遍历源字符串中出现的所有事件,并一次逐条构建新字符串:

void replaceAll(std::string& source, const std::string& from, const std::string& to)
{
    std::string newString;
    newString.reserve(source.length());  // avoids a few memory allocations

    std::string::size_type lastPos = 0;
    std::string::size_type findPos;

    while(std::string::npos != (findPos = source.find(from, lastPos)))
    {
        newString.append(source, lastPos, findPos - lastPos);
        newString += to;
        lastPos = findPos + from.length();
    }

    // Care for the rest after last occurrence
    newString += source.substr(lastPos);

    source.swap(newString);
}

这个工作!我在书店应用程序中使用了类似的方法,其中库存存储在CSV(类似于.dat文件)中。但在单字符的情况下,意味着替换者只是一个单字符,例如'|',它必须在双引号"|"中,以避免抛出无效的转换const char。

#include <iostream>
#include <string>

using namespace std;

int main()
{
    int count = 0;  // for the number of occurences.
    // final hold variable of corrected word up to the npos=j
    string holdWord = "";
    // a temp var in order to replace 0 to new npos
    string holdTemp = "";
    // a csv for a an entry in a book store
    string holdLetter = "Big Java 7th Ed,Horstman,978-1118431115,99.85";

    // j = npos
    for (int j = 0; j < holdLetter.length(); j++) {

        if (holdLetter[j] == ',') {

            if ( count == 0 ) 
            {           
                holdWord = holdLetter.replace(j, 1, " | ");      
            }
            else {

                string holdTemp1 = holdLetter.replace(j, 1, " | ");

                // since replacement is three positions in length,
                // must replace new replacement's 0 to npos-3, with
                // the 0 to npos - 3 of the old replacement 
                holdTemp = holdTemp1.replace(0, j-3, holdWord, 0, j-3); 

                holdWord = "";

                holdWord = holdTemp;

            }
            holdTemp = "";
            count++;
        }
    } 
    cout << holdWord << endl;
    return 0;
}

// result:
Big Java 7th Ed | Horstman | 978-1118431115 | 99.85

我目前使用CentOS,所以我的编译器版本如下。c++版本(g++), c++ 98默认值:

g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

我想我会使用std::replace_if()

一个简单的字符替换程序(OP要求的)可以使用标准库函数编写。

就地版本:

#include <string>
#include <algorithm>

void replace_char(std::string& in,
                  std::string::value_type srch,
                  std::string::value_type repl)
{
    std::replace_if(std::begin(in), std::end(in),
                    [&srch](std::string::value_type v) { return v==srch; },
                    repl);
    return;
}

如果输入是const字符串,则返回一个副本的重载:

std::string replace_char(std::string const& in,
                         std::string::value_type srch,
                         std::string::value_type repl)
{
    std::string result{ in };
    replace_char(result, srch, repl);
    return result;
}