Ian004
Ian004

Reputation: 195

How to read in user entered comma separated integers?

I'm writing a program that prompts the user for:

  1. Size of array
  2. Values to be put into the array

First part is fine, I create a dynamically allocated array (required) and make it the size the user wants.

I'm stuck on the next part. The user is expected to enter in a series of ints separated by commas such as: 1,2,3,4,5

How do I take in those ints and put them into my dynamically allocated array? I read that by default cin takes in integers separated by whitespace, can I change this to commas?

Please explain in the simplest manner possible, I am a beginner to programming (sorry!)

EDIT: TY so much for all the answers. Problem is we haven't covered vectors...is there a method only using the dynamically allocated array I have?

so far my function looks like this. I made a default array in main. I plan to pass it to this function, make the new array, fill it, and update the pointer to point to the new array.

int *fill (int *&array, int *limit) {

cout << "What is the desired array size?: ";                                  
while ( !(cin >> *limit) || *limit < 0 ) {
    cout << "  Invalid entry. Please enter a positive integer: ";
    cin.clear();
    cin.ignore (1000, 10);
}

int *newarr;                                                                            
newarr = new int[*limit]
    //I'm stuck here
}

Upvotes: 6

Views: 48632

Answers (9)

Prathamesh S
Prathamesh S

Reputation: 1

First, take the input as a string, then parse the string and store it in a vector, you will get your integers.

vector<int> v;
string str;
cin >> str;
stringstream ss(str);
for(int i;ss>>i;){
    v.push_back(i);
    if(ss.peek() == ','){
        ss.ignore();
    }
}
for(auto &i:v){
    cout << i << " ";
}

Upvotes: 0

RAM KUMAR
RAM KUMAR

Reputation: 1

You can use scanf instead of cin and put comma beside data type symbol

#include<bits/stdc++.h>
using namespace std;
int main()
 {
    int a[10],sum=0;
    cout<<"enter five numbers";
    for(int i=0;i<3;i++){
    scanf("%d,",&a[i]);
    sum=sum+a[i];
    }
    cout<<sum;
}

Upvotes: 0

Afaan Farooq
Afaan Farooq

Reputation: 1

#include<bits/stdc++.h>
using namespace std;
int a[1000];
int main(){
    string s;
    cin>>s;
    int i=0;
    istringstream d(s);
    string b;
    while(getline(d,b,',')){
        a[i]= stoi(b);
        i++;
    }
    for(int j=0;j<i;j++){
        cout<<a[j]<<" ";
    }
}

This code works nicely for C++ 11 onwards, its simple and i have used stringstreams and the getline and stoi functions

Upvotes: 0

vaibhav
vaibhav

Reputation: 11

#include <iostream>
using namespace std;

int main() {
    int x,i=0;
    char y;               //to store commas
    int arr[50];
    while(!cin.eof()){
        cin>>x>>y;
        arr[i]=x;
        i++;
    }

    for(int j=0;j<i;j++)
        cout<<arr[j];     //array contains only the integer part
    return 0;
}

Upvotes: 1

Mooing Duck
Mooing Duck

Reputation: 66981

All of the existing answers are excellent, but all are specific to your particular task. Ergo, I wrote a general touch of code that allows input of comma separated values in a standard way:

template<class T, char sep=','>
struct comma_sep { //type used for temporary input
    T t; //where data is temporarily read to
    operator const T&() const {return t;} //acts like an int in most cases
};
template<class T, char sep>
std::istream& operator>>(std::istream& in, comma_sep<T,sep>& t) 
{
    if (!(in >> t.t)) //if we failed to read the int
        return in; //return failure state
    if (in.peek()==sep) //if next character is a comma
        in.ignore(); //extract it from the stream and we're done
    else //if the next character is anything else
        in.clear(); //clear the EOF state, read was successful
    return in; //return 
}

Sample usage http://coliru.stacked-crooked.com/a/a345232cd5381bd2:

typedef std::istream_iterator<comma_sep<int>> istrit; //iterators from the stream
std::vector<int> vec{istrit(in), istrit()}; //construct the vector from two iterators

Since you're a beginner, this code might be too much for you now, but I figured I'd post this for completeness.

Upvotes: 5

Atul Kumar
Atul Kumar

Reputation: 373

The code can be simplified a bit with new std::stoi function in C+11. It takes care of spaces in the input when converting and throws an exception only when a particular token has started with non-numeric character. This code will thus accept input

" 12de, 32, 34 45, 45 , 23xp,"

easily but reject

" de12, 32, 34 45, 45 , 23xp,"

One problem is still there as you can see that in first case it will display " 12, 32, 34, 45, 23, " at the end where it has truncated "34 45" to 34. A special case may be added to handle this as error or ignore white space in the middle of token.

wchar_t in;
std::wstring seq;
std::vector<int> input;
std::wcout << L"Enter values : ";

while (std::wcin >> std::noskipws >> in)
{
    if (L'\n' == in || (L',' == in))
    {
        if (!seq.empty()){
            try{
                input.push_back(std::stoi(seq));
            }catch (std::exception e){ 
                std::wcout << L"Bad input" << std::endl;
            }
            seq.clear();
        }
        if (L'\n' == in) break;
        else continue;
    }
    seq.push_back(in);
}

std::wcout << L"Values entered : ";
std::copy(begin(input), end(input), std::ostream_iterator<int, wchar_t>(std::wcout, L", "));
std::cout << std::endl;

Upvotes: 0

mattnewport
mattnewport

Reputation: 14077

Victor's answer works but does more than is necessary. You can just directly call ignore() on cin to skip the commas in the input stream.

What this code does is read in an integer for the size of the input array, reserve space in a vector of ints for that number of elements, then loop up to the number of elements specified alternately reading an integer from standard input and skipping separating commas (the call to cin.ignore()). Once it has read the requested number of elements, it prints them out and exits.

#include <iostream>
#include <iterator>
#include <limits>
#include <vector>

using namespace std;

int main() {
    vector<int> vals;
    int i;
    cin >> i;
    vals.reserve(i);
    for (size_t j = 0; j != vals.capacity(); ++j) {
        cin >> i;
        vals.push_back(i);
        cin.ignore(numeric_limits<streamsize>::max(), ',');
    }
    copy(begin(vals), end(vals), ostream_iterator<int>(cout, ", "));
    cout << endl;
}

Upvotes: 1

James Kanze
James Kanze

Reputation: 154047

A priori, you should want to check that the comma is there, and declare an error if it's not. For this reason, I'd handle the first number separately:

std::vector<int> dest;
int value;
std::cin >> value;
if ( std::cin ) {
    dest.push_back( value );
    char separator;
    while ( std::cin >> separator >> value && separator == ',' ) {
        dest.push_back( value );
    }
}
if ( !std::cin.eof() ) {
    std::cerr << "format error in input" << std::endl;
}

Note that you don't have to ask for the size first. The array (std::vector) will automatically extend itself as much as needed, provided the memory is available.

Finally: in a real life example, you'd probably want to read line by line, in order to output a line number in case of a format error, and to recover from such an error and continue. This is a bit more complicated, especially if you want to be able to accept the separator before or after the newline character.

Upvotes: 4

Victor
Victor

Reputation: 14622

You can use getline() method as below:

#include <vector>
#include <string>
#include <sstream>

int main() 
{
  std::string input_str;
  std::vector<int> vect;

  std::getline( std::cin, input_str );

  std::stringstream ss(str);

  int i;

  while (ss >> i)
  {
    vect.push_back(i);

    if (ss.peek() == ',')
    ss.ignore();
  }
}

The code is taken and processed from this answer.

Upvotes: 2

Related Questions