专业编程基础技术教程

网站首页 > 基础教程 正文

C++|string类的replace()有点反操作习惯

ccvgpt 2024-07-21 17:42:08 基础教程 12 ℃

在文本编辑器中,我们做文本替换时,都是用一个新字符串来替换另一个旧字符串。

MFC将字符串封装为CString类,其方法Replace()符合文本编辑器的操作习惯:

C++|string类的replace()有点反操作习惯

int Replace( TCHAR chOld, TCHAR chNew );
int Replace( LPCTSTR lpszOld, LPCTSTR lpszNew );

但C++ STL中的string类的replace()却有点违反一般的操作习惯,对于Old文本不是直接指定,而是用一段距离(用数字或迭代器来指定一段文本空间范围)来表示,且只做一次替换:

// 以下是重载的一些方法
string (1)	
string& replace (size_t pos,  size_t len,  const string& str);
string& replace (iterator i1, iterator i2, const string& str);
substring (2)	
string& replace (size_t pos,  size_t len,  const string& str,
                 size_t subpos, size_t sublen);
c-string (3)	
string& replace (size_t pos,  size_t len,  const char* s);
string& replace (iterator i1, iterator i2, const char* s);
buffer (4)	
string& replace (size_t pos,  size_t len,  const char* s, size_t n);
string& replace (iterator i1, iterator i2, const char* s, size_t n);
fill (5)	
string& replace (size_t pos,  size_t len,  size_t n, char c);
string& replace (iterator i1, iterator i2, size_t n, char c);
range (6)	
template <class InputIterator>
string& replace (iterator i1, iterator i2,  InputIterator first, InputIterator last);

变通的做法就是先要使用find()方法,找出其起始位置,再使用size()方法,求出需要替换的字符个数,然后再应用replace(),所以还要做一下如下的封装:

void replaceChars(string& modifyMe,
                  const string& findMe, const string& newChars) {
    // Look in modifyMe for the "find string"
    // starting at position 0:
    size_t i = modifyMe.find(findMe, 0);
    // Did we find the string to replace?
    if(i != string::npos)
        // Replace the find string with newChars:
        modifyMe.replace(i, findMe.size(), newChars);
}
string& replaceAll(string& context, const string& from,
                   const string& to) {
    size_t lookHere = 0;
    size_t foundHere;
    while((foundHere = context.find(from, lookHere))   != string::npos) {
    context.replace(foundHere, from.size(), to);
    lookHere = foundHere + to.size();
  }
  return context;
}

STL <algorithm>倒是实现了通用的replace()算法,但针对的却是单个的字符(因为其是以序列窗口中的元素的操作对象):

  string s("aaaXaaaXXaaXXXaXXXXaaa");
  replace(s.begin(), s.end(), 'X', 'Y');

所以你会明白,string也是属于序列类容器,其操作的对象是单个的char。这也是需要与其它序列类容器保持一致的风格,包括迭代器及应用其上的算法,所以其重载的replace()方法就有点违反直觉。而CString的Replace()却没有这些方法的考量或限制,比较符合一般的操作习惯。

string类各种重载的replace()方法的实例:

/*用法一:  
 *用str替换指定字符串从起始位置pos开始长度为len的字符  
 *string& replace (size_t pos, size_t len, const string& str);  
 */    
int main()    
{    
    string line = "this@ is@ a test string!";    
    line = line.replace(line.find("@"), 1, ""); // 从第一个@位置替换第一个@为空    
    cout << line << endl;  
    return 0;    
}    
//运行结果:
//this is@ a test string!     

/*用法二:  
 *用str替换 迭代器起始位置 和 结束位置 的字符  
 *string& replace (const_iterator i1, const_iterator i2, const string& str);  
 */    
int main()    
{    
    string line = "this@ is@ a test string!";    
    line = line.replace(line.begin(), line.begin()+6, "");  
    //用str替换从begin位置开始的6个字符    
    cout << line << endl;       
    return 0;    
}   
//运行结果:
//is@ a test string!

/*用法三:  
 *用substr的指定子串(给定起始位置和长度)替换从指定位置上的字符串  
 *string& replace (size_t pos, size_t len, const string& str, size_t subpos, size_t sublen);  
 */    
int main()    
{    
    string line = "this@ is@ a test string!";    
    string substr = "12345";    
    line = line.replace(0, 5, substr, substr.find("1"), 3); 
    //用substr的指定子串(从1位置数共3个字符)替换从0到5位置上的line    
    cout << line << endl;       
    return 0;    
}   
//运行结果:
//123 is@ a test string!

/*用法四:string转char*时编译器可能会报出警告,不建议这样做  
 *用str替换从指定位置0开始长度为5的字符串  
 *string& replace(size_t pos, size_t len, const char* s);  
 */    
int main()    
{    
    string line = "this@ is@ a test string!";    
    char* str = "12345";    
    line = line.replace(0, 5, str); //用str替换从指定位置0开始长度为5的字符串    
    cout << line << endl;       
    return 0;    
}    
//运行结果:
//12345 is@ a test string!

/*用法五:string转char*时编译器可能会报出警告,不建议这样做  
 *用str替换从指定迭代器位置的字符串  
 *string& replace (const_iterator i1, const_iterator i2, const char* s);  
 */    
int main()    
{    
    string line = "this@ is@ a test string!";    
    char* str = "12345";    
    line = line.replace(line.begin(), line.begin()+9, str); 
    //用str替换从指定迭代器位置的字符串    
    cout << line << endl;       
    return 0;    
}  
//运行结果:
//12345 a test string!

/*用法六:string转char*时编译器可能会报出警告,不建议这样做  
 *用s的前n个字符替换从开始位置pos长度为len的字符串  
 *string& replace(size_t pos, size_t len, const char* s, size_t n);  
 */    
int main()    
{    
    string line = "this@ is@ a test string!";    
    char* str = "12345";    
    line = line.replace(0, 9, str, 4);  //用str的前4个字符替换从0位置开始长度为9的字符串    
    cout << line << endl;       
    return 0;    
}    
//运行结果:
//1234 a test string!

/*用法七:string转char*时编译器可能会报出警告,不建议这样做  
 *用s的前n个字符替换指定迭代器位置(从i1到i2)的字符串  
 *string& replace (const_iterator i1, const_iterator i2, const char* s, size_t n);  
 */    
int main()    
{    
    string line = "this@ is@ a test string!";    
    char* str = "12345";    
    line = line.replace(line.begin(), line.begin()+9, str, 4);  
    //用str的前4个字符替换指定迭代器位置的字符串    
    cout << line << endl;       
    return 0;    
}    
//运行结果:
//1234 a test string!

/*用法八:  
 *用重复n次的c字符替换从指定位置pos长度为len的内容  
 *string& replace (size_t pos, size_t len, size_t n, char c);  
 */    
int main()    
{    
    string line = "this@ is@ a test string!";    
    char c = '1';    
    line = line.replace(0, 9, 3, c);    //用重复3次的c字符替换从指定位置0长度为9的内容    
    cout << line << endl;       
    return 0;    
}    
//运行结果:
//111 a test string!

/*用法九:  
 *用重复n次的c字符替换从指定迭代器位置(从i1开始到结束)的内容  
 *string& replace (const_iterator i1, const_iterator i2, size_t n, char c);  
 */    
int main()    
{    
    string line = "this@ is@ a test string!";    
    char c = '1';    
    line = line.replace(line.begin(), line.begin()+9, 3, c);    
    //用重复3次的c字符替换从指定迭代器位置的内容    
    cout << line << endl;       
    return 0;    
}  
//运行结果:
//111 a test string!

综合实例:

#include <iostream>
#include <string>
using namespace std;
int main ()
{
    string var ("abcdefghijklmn");
    const string dest ("1234");
    string dest2 ("567891234");
    var.replace (3,3, dest);
    cout << "1: " << var << endl; // 1: abc1234ghijklmn
    var = "abcdefghijklmn";
    var.replace (3,1, dest.c_str(), 1, 3);
    cout << "2: " << var << endl; //2: abc234efghijklmn
    var ="abcdefghijklmn";
    var.replace (3, 1, 5, 'x');
    cout << "3: " << var << endl; // 3: abcxxxxxefghijklmn
    string::iterator itA, itB;
    string::iterator itC, itD;
    itA = var.begin();
    itB = var.end();
    var = "abcdefghijklmn";
    var.replace (itA, itB, dest);
    cout << "4: " << var << endl; //4: 1234
    itA = var.begin ();
    itB = var.end();
    itC = dest2.begin () +1;
    itD = dest2.end ();
    var = "abodefghijklmn";
    var.replace (itA, itB, itC, itD);
    cout << "5: " << var << endl; //5: 67891234efghijklmn
    var = "abcdefghijklmn";
    var.replace (3, 1, dest.c_str(), 4); //这种方式会限定字符串替换的最大长度
    cout <<"6: " << var << endl;
    return 0;
}
/*
程序执行结果为:
1: abc1234ghijklmn
2: abc234efghijklmn
3: abcxxxxxefghijklmn
4: 1234
5: 67891234efghijklmn
6: abc1234efghijklmn
*/

ref

http://www.cplusplus.com/reference/algorithm/replace/?kw=replace

-End-

Tags:

最近发表
标签列表