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.
source to share
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';
}
}
source to share
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.
}
source to share