删除每行括号之间的部分(如果存在)

Removing section between parenthesis on every line if present

本文关键字:如果 存在 之间 删除      更新时间:2023-10-16

我要输入一个文件,其中有一堆看起来像(* blah blah 4324 blah*) 23的行。我试图删除括号之间的所有内容,并保留右括号后面的数字。

ifstream infile{"nums.txt"};
istream_iterator<string> infile_begin_iter {infile};
istream_iterator<string> eof;
vector<string> cleanNums {infile_begin_iter, eof};
for(int i=0; i<cleanNums.size(); i++){
    int openParen=cleanNums[i].find("(*");
    int closeParen=cleanNums[i].find("*)");
    int distance=openParen-closeParen;
    cleanNums[i].erase(closeParen, distance);
}

那段代码一直导致我的程序崩溃。我一直在这里寻找不同的东西,比如getline但我发现它只显示分隔符之前的所有内容

由于没有给出声明,我假设cleanNumsstd::vector<std::string>

现在到问题的代码片段:std::string::find()返回size_type(即通常是一些整数类型),用于找到给定字符串的位置。因此,openParencloseParen将是找到左圆括号和右圆括号的索引——如果能找到它们的话。当使用size_type类型的参数调用std::string::erase()时,将这些参数解释为要擦除的部分的起始索引和长度。然而,你叫它好像它在开始索引和最后索引的部分,将被删除。所以你要做的就是在传递给erase()之前,使用这两个索引来计算要删除的部分的长度。

还有另一个问题,可能是导致你的程序崩溃的问题:你没有检查两个std::string::find()调用是否真的找到了一些东西。因为如果没有,那么它们返回std::string::npos,这通常比大多数字符串的大小都大。这导致索引超出范围,并且std::string::erase()抛出std::out_of_range异常。砰,程序崩溃了!

那么,这里的教训是什么呢?如果你不确定,不要假设函数/方法需要什么样的参数,但是可以在你最喜欢的c++参考中查找。如果编译器不阅读它使用/编译的函数的文档,这是可以的,但是程序员应该阅读他/她至少使用一次的函数的文档。

您可以使用std::getline读取结束的')'字符,然后您知道下一次读取将是您的号码:

int main()
{
    std::ifstream ifs("test.txt");
    std::string skip; // read in parts you want to skip
    int value;        // the value you want to keep
    // skip data upto and past ')', then read number
    while(std::getline(ifs, skip, ')') >> value)
        std::cout << "found: " << value << 'n'; // output just the number
}