替换函数中的运行时错误?

Runtime error in replace function?

我写了一个程序来查找和替换文件中的一行。程序是这样的:

#include<iostream>
#include<fstream>
#include<string>
using namespace std;
int main(){
    fstream f,g; string s,s2,s3;
    f.open("sasuke.txt",ios::in);
    g.open("konoha.txt",ios::out);
    cout<<"Enter line to be replaced: "<<endl;
    getline(cin,s2);
    cout<<"To be replaced with? "<<endl;
    getline(cin,s3);
    while(getline(f,s)){
        s.replace(s.find(s2),s2.size(),s3);
        g<<s<<endl;
    }
    g.close();
    f.close();
    return 0;
}

我得到的错误是

terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::replace: __pos (which is 18446744073709551615) > this->size() (which is 105)
Aborted (core dumped)

谁能解释一下为什么会出现这个错误以及如何解决?

事情是这样的。假设您要替换的行是 "src",它将被替换为 "dst"。现在,您的程序遍历输入文本文件 line-by-line,并在发现 "src" 时将其替换为 "dst"。但是,在某个时间点,它会遇到不包含任何文本的行 "src"。然后,找到 returns 一些无效的数字,程序终止并抱怨您提供的替换位置无效。

假设您的 sasuke.txt 如下:

this is src
this line has src
this line too has src
but not this line

现在,您的代码将 运行 直到最后一行终止。为了证明这一点,我在 while 循环中添加了一点 cout。查看输出:

Enter line to be replaced: 
src
To be replaced with? 
dst
in the while loop
this is src
in the while loop
this line has src
in the while loop
this line too has src
in the while loop
but not this line
terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::replace: __pos (which is     18446744073709551615) > this->size() (which is 17)

解决方法是先做find()操作,看返回的position是否有效,再执行replace。对我来说这很有效:

while(getline(f,s)){
    size_t pos = s.find(s2);
    if(pos < s.length())
        s.replace(pos,s2.size(),s3);
    g<<s<<endl;
}