Search code examples
c++findstdstringerase

Removing section between parenthesis on every line if present


I have a file that I am inputting that has a bunch of lines that look like (* blah blah 4324 blah*) 23. I'm trying to remove everything between the parenthesis and keep the number that's just after the closed parenthesis.

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);
}

That code keeps causing my program to crash. I have been looking around here for different things like getline but there I find it only shows me everything before the deliminator.


Solution

  • Since there is no declaration given, I assume that cleanNums is a std::vector<std::string>.

    Now to the code snippet from the question: std::string::find() returns a size_type (i.e. usually some integer type) for the position where the given string was found. So openParen and closeParen will be the index where the opening and closing parenthesis are found - if they are found at all. std::string::erase(), when called with size_type-typed arguments interprets these arguments as starting index and length of the part that shall be erased. However, you call it as if it where the starting index and the last index of the part that shall be removed. So what you have to do is to use these both indices to calculate the length of the part that shall be removed before passing it to erase().

    And there is another problem, probably the one which causes your program to crash: You do not check whether both std::string::find() calls actually found something. Because if the do not, then they return std::string::npos, which is usually larger than the size of most strings. That results in the indices being out of range, and std::string::erase() throws a std::out_of_range exception. Boom, program crash!

    So, what is the lesson here? Do not assume what kind of parameters a function/method expects, if you are not sure about that, but look it up in your favourite C++ reference. It is OK if the compiler does not read the documentation of a function it uses/compiles, but the programmer should read the documentation of a function he/she uses at least once.