Unknown input size cin

I'm sure this is a simple problem. This should be honestly the simplest part of writing a SAT solver, but I should have custom input like this:

Sample Input:
1              <-- 1st number denotes the number of cases I will have
5              <-- 2nd number represents the number of variables, followed 
1 2 3              who knows how many clauses.
-1 3 4
-2 -3 5
-5 -1 2
-4 1 -2
-4 -1 -2 -3 -5

*blank line separates the different cases*
.... followed by as many cases as the user said they had

      

So, I store these sentences in string vectors and they all go into another vector. So what would be the best way to get this input from the user? The fact that the number of sentences is not initially given is the part that mostly confuses me. I would try for a while () ... But I don't know how to stop it. I guess I'm a little unsure how cin will work in this situation.

Thank you for your help.

+3


source to share


2 answers


There are two separate problems: (a) read an unknown number of input lines and (b) parse a given input line into an unknown number of int

s.

First, reading lines from input. It's simple std::getline

:

std::string str
while (std::getline(std::cin, str)) {
    // ???
}

      

Then, given str

, we have to parse it for int

s. The easiest way is to put it in stream :

std::istringstream iss(str);

      

And then read int

one by one:



int i;
while (iss >> i) {
    // do something
}

      

Or put all of them in at vector

once, passing a pair to it istream_iterator<int>

:

std::vector<int> v{std::istream_iterator<int>{iss},
                   std::istream_iterator<int>{}};

      

So a complete example that logs the sum of each line of input would be:

std::string str
while (std::getline(std::cin, str)) {
    std::istringstream iss(str);
    std::vector<int> v{std::istream_iterator<int>{iss},
                       std::istream_iterator<int>{}};

    if (!v.empty()) {
        std::cout << "sum=" << std::accumulate(v.begin(), v.end(), 0) << '\n';
    }
}

      

+5


source


This is very common in homework and competition questions, and the answer goes like this:



#include <sstream> //you may not have known about this

int num_cases = 0;
std::cin >> num_cases;
for(int case_num=0; case_num<num_cases; ++case_num) { //for each case       
    std::vector<std::vector<int>> variables;
    int num_variables = 0;
    std::cin >> num_variables;
    std::cin.ignore(1); //ignore the newline character, it messes with getline
    for(int var=0; var<num_variables; ++var) { //for each variable
        std::string linestr;
        std::getline(std::cin, linestr, '\n'); //read whole line into string
        std::istringstream linestream(linestr); //make a stream from the line

        int newclause = 0;
        std::vector<int> lineclauses;
        while(linestream >> newclause) //for each clause
            lineclauses.push_back(newclause); //add it to the row
        //when that fails, we read the whole line
        variables.push_back(lineclauses); //so add the row to 'variables'
    }
    //Do stuff with variables vector.
}

      

+3


source







All Articles