skr
skr

Reputation: 944

Elegant solution to take input to a vector<int>

I am trying to create an vector <int> whose size is not pre-defined. It should take in numbers as long as there are numbers in the input terminal and should stop reading when I hit Enter. I tried many solutions including the ones given here and here. In the second case, I can enter a non-integer to terminate the input to the vector. If I use the first solution (code added below), it listens to the input indefinitely.

Code:

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>

using std::cout;
using std::cin;
using std::vector;
using std::string;
using std::istringstream;

int main()
{
    //cout << "Enter the elements of the array: \n";
    //vector <int> arr ( std::istream_iterator<int>( std::cin ), std::istream_iterator<int>() );
    vector <int> arr;
    string buf;
    cout << "Enter the elements of the array: \n";
    while(getline(cin, buf))
    {
        istringstream ssin(buf);
        int input;
        while(ssin >> input)
        {
            arr.push_back(input);
        }
    }

    cout << "The array: \n";
    for(size_t i = 0; i < arr.size(); i++)
    {
        cout << arr[i] << " ";
    }
    return 0;
}

1) I don't feel that typing in a character or a very large number to end listening to input is very elegant. However, the solution with istringstream seems to be the way to go. I am not sure why it doesn't work.

2) Is there any way to detect the Enter from keyboard to terminate listening to input? I tried using cin.get(), but it changed the numbers in the vector.

3) Any other methods or suggestions?

Upvotes: 0

Views: 2367

Answers (2)

Jerry Coffin
Jerry Coffin

Reputation: 490218

Let's take things one step at a time.

We want to read up until enter is pressed. That means you probably want to use std:getline to read a line.

Then you want to parse it, so you want to put the line into an istringstream.

Then you want to read numbers. While you're reading them, you apparently want to ignore anything other than digits, and you want to keep reading even if you get to a group of digits that can't be converted to a number.

That leaves a few things that aren't entirely clear, such as what to do with that input that's too large to convert? Do you want to just skip to the next? Do you want to read some digits as a number, then read remaining digits as another number?

Likewise, what do you want to do if you get something like "123a456"? Should it be skipped completely, read as "123" (and the "a456" ignored)? Should it be read as "123" and "456", and just the "a" ignored?

For the moment let's assume that we're going to read space-separated groups of characters, and convert all those to numbers that we can. If something is too big to convert to a number, we'll ignore it (in its entirety). If we have a group like "123a456", we'll read the "123" as a number, and ignore the "a456".

To achieve this, we can do something like this:

std::string line;
std::getline(infile, line);

std::istringstream input(line);

std::string word;
std::vector<int> output;

while (input >> word) {
    try {
        int i = std::stoi(word);
        output.push_back(i);
    }
    catch (...) {}
}

For example, given input like: "123a456 321 1111233423432434342343223344 9", this will read in [123, 321, 9].

Of course, I'm just taking a guess about your requirements, and I haven't worked at making this particularly clean or elegant--just a straightforward implementation of one possible set of requirements.

Upvotes: 1

skr
skr

Reputation: 944

Please see the comments from @LearningC and @M.M.

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>

using std::cout;
using std::cin;
using std::vector;
using std::string;
using std::istringstream;

int main()
{
    vector <int> arr;
    string buf;
    int input;
    cout << "Enter the elements of the array: \n";
    getline(cin, buf);
    istringstream ssin(buf);
    while(ssin >> input)
    {
        arr.push_back(input);
    }

    cout << "The array: \n";
    for(size_t i = 0; i < arr.size(); i++)
    {
        cout << arr[i] << " ";
    }
    return 0;
}

Upvotes: 0

Related Questions