How to use cin with variable number of inputs?

Yesterday I participated in a programming contest, and we needed to read the form input

n a1 a2 ... an m b1 b2 ... bm ... 

where the first line indicates how many inputs there are, and the next line contains many inputs (and all inputs are integers).

I know if each line has the same number of inputs (say 3), we can write something like

 while (true) { cin >> a1 >> a2 >> a3; if (end of file) break; } 

But how do you do this when each row can have a different number of inputs?

+5
source share
7 answers

Here is a simple example using only standard libraries:

 #include <vector> // for vector #include <iostream> // for cout/cin, streamsize #include <sstream> // for istringstream #include <algorithm> // for copy, copy_n #include <iterator> // for istream_iterator<>, ostream_iterator<> #include <limits> // for numeric_limits int main() { std::vector<std::vector<double>> contents; int number; while (std::cin >> number) { std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // skip eol std::string line; std::getline(std::cin, line); if (std::cin) { contents.emplace_back(number); std::istringstream iss(line); std::copy_n(std::istream_iterator<double>(iss), number, contents.back().begin()); } else { return 255; } } if (!std::cin.eof()) std::cout << "Warning: end of file not reached\n"; for (auto& row : contents) { std::copy(row.begin(), row.end(), std::ostream_iterator<double>(std::cout," ")); std::cout << "\n"; } } 

Watch live on Coliru : input

 5 1 2 3 4 5 7 6 7 8 9 10 11 12 

Output:

 1 2 3 4 5 6 7 8 9 10 11 12 
+7
source

you can do it this way

 #include<vector> ... ... std::vector<sometype> a; sometype b; std::cin >> b; while(std::cin) { a.push_back(b); std::cin >> b; } 

You can enter any number of items, and when you are finished, send an EOF signal.

+2
source

Your algorithm will look something like this:

 1. read the 'number' of inputs, say n1 2. set up a loop to read the n1 inputs 3. check if the user has more inputs to give if YES repeat the steps 1,2 and 3 till all inputs are taken and stored. else move on... 

You can use a for or while loop and store the entries in an array.

Hope this helps!

+1
source

Because people complained, as I called my first answer, “easy to do,” here's the correct version using Boost Spirit:

 #include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/phoenix.hpp> int main() { typedef std::vector<std::vector<double>> data_t; typedef boost::spirit::istream_iterator It; std::cin.unsetf(std::ios::skipws); It first(std::cin), last; bool ok; data_t contents; { using namespace boost::spirit::qi; static rule<It, data_t(), blank_type, locals<int>> file; static rule<It, std::vector<double>(int number), blank_type> row; _a_type number; // friendly alias file %= -(omit [int_[number=_1]] > eol > row(number)) % eol; row = repeat(_r1) [ double_ ]; ok = phrase_parse(first, last, file, blank, contents); } if (ok) for (auto& row : contents) { std::copy(row.begin(), row.end(), std::ostream_iterator<double>(std::cout," ")); std::cout << "\n"; } if (first!=last) std::cout << "Warning: end of file not reached, remaining unparsed: '" << std::string(first, last) << "'\n"; } 

He is clearly far superior

  • it uses much less lines included :)
  • compilation (without optimization) requires ~ 10 times, another 16% longer with optimization
  • Meta programming requires about 5 years of training in meta programming (jokes, docs / tutorials are fine).
  • on a serious account: it is much more flexible

    • can be expanded to analyze other structural elements, more complex
    • can implement semantics on the fly
    • correctly analyze NaN and +/- infinity.
    • and etc.

Watch Live on Coliru , and

+1
source

Given the format you specify, this is what I would like to do.

 for (int n; std::cin >> n; ) { if (n == 0) // Test for end of input break; for (int i = 0; i != n; ++i) { int x; std::cin >> x; if (!std::cin) break; // Valid input x. Now do something with x like // v.push_back(x) where v is some vector of ints } } // Did we succeed? if (!std::cin) { // Something went bad. std::cerr << "Error reading input" << std::endl; return EXIT_FAILURE; } 
+1
source

Simple, use a for loop and an array.

 int a[MAX]; // programming problems usually specify a max size for(i=0;i<n;i++) cin>>a[i]; 
0
source

A simple solution using arrays and dynamic memory allocation to obtain a variable number of inputs of a predefined type.

 #include<iostream> using namespace std; int main(){ int n; cout<<"Enter the number of elements"<<endl; cin>>n; int *c=new int[n]; for(int k=0;k<n;k++) cin>>c[k]; delete c; } 
0
source

Source: https://habr.com/ru/post/1498648/


All Articles