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

Removing section between parenthesis on every line if present

我有一个正在输入的文件,其中有一堆行看起来像 (* 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,但我发现它只显示了分隔符之前的所有内容。提前致谢。

您可以使用 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
}

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

现在转到问题的代码片段:std::string::find() returns a size_type(即通常是某种整数类型),用于找到给定字符串的位置。所以 openParencloseParen 将是找到左括号和右括号的索引 - 如果找到它们的话。 std::string::erase(),当使用 size_type 类型的参数调用时,将这些参数解释为应擦除的部分的起始索引和长度。但是,您将其称为应删除部分的起始索引和最后索引。因此,您要做的是使用这两个索引来计算在将其传递给 erase() 之前应删除的部分的长度。

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

那么,这里的教训是什么? 不要假设 function/method 期望什么样的参数,如果你不确定,但是在你最喜欢的 C++ 参考资料中查找.如果编译器不阅读它 uses/compiles 的函数的文档是可以的,但是程序员应该阅读 he/she 至少使用过一次的函数的文档。