template boy
template boy

Reputation: 10490

How do I break out of a getline with a file?

I have code where I am inputting stuff from a file. My txt file looks like this:

file.txt

hello world
...
1 2

The numbers at the bottom are supposed to be read into variables. As for "hello world", it should be picked up by getline. But I don't know how many lines there will be in the txt file so I don't know how to break out of it. Here is my code:

while (getline(file, line))
{
    std::cout << line << std::endl;
    // ...
}

file >> a >> b; // 1 2

If I was doing this with cin I could just do Ctrl+Z to stop getline loop from running. How do I break out of the while loop at the right time before I get to 1 2?

Upvotes: 0

Views: 848

Answers (3)

herohuyongtao
herohuyongtao

Reputation: 50717

For each line string line, you can put it into an istringstream iss. And then try to stream it into a and b using iss >> a >> b, if it can be done successfully, it means you enter the right line. Otherwise, you go on checking the next line.

int a, b;
while (getline(file, line))
{
    istringstream iss(line);

    if (iss >> a >> b)
    {
        // you are in the right line, and a,b has the values e.g. 1 2
    }
}

It should also work for other strings besides "hello world", like "aaa bbb cc" etc. as long as they are not the numbers you are looking for.

P.S.: you can also take use of regex if you use C++11 to check if given line has/matches the pattern you are looking for.

Upvotes: 1

James Kanze
James Kanze

Reputation: 154047

It's not too clear how you determine that you want to break out of the loop. What is the criterion? If you want to read all lines but the last, the simplest solution is to simply read all of the lines into an std::vector<std::string>, and then process that; you can iterate over a vector until the next to the last element (which you can't do on a stream). If it's some pattern your looking to match (say "\\d+\\s+\\d+"), then you can add this to the condition:

std::string line;
std::regex matchNumbers( "\\d+\\s+\\d+" );
while ( std::getline( file, line ) && ! regex_match( line, matchNumbers ) ) {
    //  ...
}
std::istringstream numbers( line );
numbers >> a >> b;

And so on.

Upvotes: 0

JBL
JBL

Reputation: 12927

Use a condition, and a break; statement.

E.g.:

while (getline(file, line))
{
    std::cout << line << std::endl;
    // ...
    if(line == "hello world"/){
        break;//Exits the loop
    }
}

A break statement makes your code exit the most inner loop it's used in. In this case, it exits the while loop.

EDIT: If you don't want to break on a specific line, then you'll better use regular expression or another mechanism (like std::stringstream) to find a match of the string you're looking for, and capture the part you're interested in. I suggest you take a look at Boost.Regex for this.

The idea is to loop on the lines, i.e. just as you do. As soon as you have a match, you can break (the same way) and capture from the string you're currently reading (which in your code would be in the line variable).

Upvotes: 1

Related Questions