Stringstream parse comma-separated integers - c++

So guys, Actually What I wanna do here is that when I input 3,12,36 the output will be:
3
12
36
But here I have difficulty on how to make it output all the answer. What I have been doing is that when you input 3,12,36 it will output 3 12 only and if you type 3,12,36,48 it will output 3 12 36.
So it will always miss the last integer because my while loop is not correct I guess. but if I change it into
while(output >> life|| output >> ch)
It doesn't work either. I've done a lot of research but it still makes me confused and I'm still stuck on this part.
vector<int> parseInts(string str) {//23,4,56
vector<int>lifeishard;
stringstream output;
string lifeisgood = str;
output.str(lifeisgood);
int life;
char ch;
while(output >> life >> ch){
lifeishard.push_back(life);
//lifeishard.push_back(life2);
//lifeishard.push_back(life3);
}
return lifeishard;
}
int main() {
string str;
cin >> str;
vector<int> integers = parseInts(str);
for(int i = 0; i < integers.size(); i++) {
cout << integers[i] << "\n";
}
return 0;
}

On your last number, the while loop fails because there's no character at the end. Just the end of the string. So it doesn't execute the push_back inside the loop.
Change it so that the while loop just gets the number. Then do the push_back in the loop. Then in the loop, after the push, get the comma character. Don't bother checking for failure getting the comma because when it goes around the while loop again it will fail and exit.
I changed to using getline in your main. I changed your loop index to size_t because it is never a good idea to mix signed and unsigned integers, and whenever you use a size() function, it's a size_t. When posting your program it really should include everything. My fixed up version of your program:
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
using namespace std;
vector<int> parseInts(string str) {//23,4,56
vector<int>lifeishard;
stringstream output;
string lifeisgood = str;
output.str(lifeisgood);
int life;
char ch;
while(output >> life){
lifeishard.push_back(life);
output >> ch;
}
return lifeishard;
}
int main() {
string str;
getline(cin, str);
vector<int> integers = parseInts(str);
for(size_t i = 0; i < integers.size(); i++) {
cout << integers[i] << "\n";
}
// Here is how we do for loops over containers in modern C++
for(auto x: integers) {
cout << x << '\n';
}
return 0;
}

A combination of stringstream, getline with delimiter and stoi would be enough for the conversion:
From the C++ reference for getline with delimiter:
Extracts characters from is and stores them into str until the delimitation character delim is found.
With this in mind, the code example below assumes the input is well-formed:
Example
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
vector<int> parseInts(const string& str, const char delim = ',')
{
vector<int> parsed;
stringstream ss(str);
string s;
while (getline(ss, s, delim)) // <- stores input in s upon hitting delimiter
parsed.push_back(stoi(s)); // <-- convert string to int and add it to parsed
return parsed;
}
int main()
{
string str = "3,12,36"; // <-- change to cin if you'd like
vector<int> ints = parseInts(str);
for (auto& i : ints)
cout << i << "\n";
}
Output
3
12
36
See more: getline, stoi

Related

How would I split up user input into a char and an integer?

I am working on a project where I have to parse data from user input.
#include <iostream> // for cin and cout
#include <iomanip> // for setw()
#include <cctype> // for toupper()
using namespace std;
int main(){
string playerInput;
cin >> playerInput;
//Player would input strings like C13,C 6, I1, Z 16, etc...
}
return 0;
I've tried something like this, which kinda works but only if the letter proceeds the number in the string.
int myNr = std::stoi(playerInput);
What my end goal is to grab the letter and number from the string, and place them in a char variable and a integer variable respectively. I am stuck on how to proceed from here and could use some help, thanks!
This is the simplest and the shortest way to achieve that (it also ignores spaces and tabs):
int main() {
char ch;
int n;
cin >> ch >> n;
cout << "ch = " << ch << ", n = " << n << endl;
}
I think that other answers are a bit overcomplicated.
You could do like what you had:
char letter = playerInput.front();
playerInput.erase(0);
int number = std::stoi(playerInput);
Of course, that doesn't allow for spaces. Removing spaces can be quite tedious, but it could be done like:
playerInput.erase(
std::remove_if(
begin(playerInput), end(playerInput),
[](uint8_t ch) { return std::isspace(ch); }),
end(playerInput));
Full Demo
Live On Coliru
#include <cctype> // for toupper()
#include <iomanip> // for setw()
#include <iostream> // for cin and cout
#include <algorithm> // for remove_if
static bool ignorable(uint8_t ch) {
return std::isspace(ch)
|| std::ispunct(ch);
}
int main() {
std::string playerInput;
while (getline(std::cin, playerInput)) {
playerInput.erase(
std::remove_if(
begin(playerInput), end(playerInput),
ignorable),
end(playerInput));
if (playerInput.empty())
continue;
char letter = playerInput.front();
playerInput.erase(begin(playerInput));
int number = std::stoi(playerInput);
std::cout << "Got: " << letter << " with " << number << "\n";
}
}
Prints
Got: C with 13
Got: C with 6
Got: I with 1
Got: Z with 16
You have the right idea in using std::stoi. My code expands your approach:
string playerInput;
getline(cin, playerInput);
char c1 = playerInput[0];
int num = stoi(playerInput.substr(1));
The above code receives an input string, then takes out the first character and uses std::stoi on the rest of the string.
Note that I use std::getline to account for the possibility of there being spaces in the input. If you are doing this repeatedly, you will need to add cin.ignore() after each getline() statement. See this link for more info.
std::cin stops reading input when it encounters a space. You can use std::getline() if your input has spaces. To parse your string, you should check out std::stringstream. It allows you to read from a string as if it were a stream like std::cin.
#include <iostream> // for cin and cout
#include <iomanip> // for setw()
#include <cctype> // for toupper()
#include <sstream>
int main(){
std::string playerInput;
int i;
char c;
std::getline(std::cin, playerInput); // Remove trailing newline
std::getline(std::cin, playerInput);
//Player would input strings like C13,C 6, I1, Z 16, etc...
//String Stream
std::stringstream playerInputStream(playerInput);
//Read as if you were reading through cin
playerInputStream >> c; //
playerInputStream >> i;
}
return 0;

How to user input the array elements in c++ in one line

I am new to c++ , Basically I belong to PHP . So I am trying to write a program just for practice, to sort an array . I have successfully created the program with static array value that is
// sort algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::sort
#include <vector> // std::vector
bool myfunction (int i,int j) { return (i<j); }
struct myclass { bool operator() (int i,int j) { return (i<j);} } myobject;
int main () {
int myints[] = {55,82,12,450,69,80,93,33};
std::vector<int> myvector (myints, myints+8);
// using default comparison (operator <):
std::sort (myvector.begin(), myvector.begin()+4);
// using function as comp
std::sort (myvector.begin()+4, myvector.end(), myfunction);
// using object as comp
std::sort (myvector.begin(), myvector.end(), myobject);
// print out content:
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
its output is ok . But I want that the elements should input from user with space separated or , separated . So i have tried this
int main () {
char values;
std::cout << "Enter , seperated values :";
std::cin >> values;
int myints[] = {values};
/* other function same */
}
it is not throwing an error while compiling. But op is not as required . It is
Enter , seperated values :20,56,67,45
myvector contains: 0 0 0 0 50
3276800 4196784 4196784
------------------ (program exited with code: 0) Press return to continue
You can use this simple example:
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
using namespace std;
int main()
{
stringstream ss;
string str;
getline(cin, str);
replace( str.begin(), str.end(), ',', ' ');
ss << str;
int x = 0;
while (ss >> x)
{
cout << x << endl;
}
}
Live demo
or, if you want to have it more generic and nicely enclosed within a function returning std::vector:
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
using namespace std;
template <typename T>
vector<T> getSeparatedValuesFromUser(char separator = ',')
{
stringstream ss;
string str;
getline(cin, str);
replace(str.begin(), str.end(), separator, ' ');
ss << str;
T value{0};
vector<T> values;
while (ss >> value)
{
values.push_back(value);
}
return values;
}
int main()
{
cout << "Enter , seperated values: ";
auto values = getSeparatedValuesFromUser<int>();
//display values
cout << "Read values: " << endl;
for (auto v : values)
{
cout << v << endl;
}
}
Live demo
Read in all the values into one string, then use a tokenizer to separate out the individual values.
How do I tokenize a string in C++?
The above answers are very good for an arbitrary number of inputs, but if you allready know how many numbers will be put, you could do it like:
int[5] intList;
std::cin >> intList[0] >> intList[1] >> intList[2] >> intList[3] >> intList[4]
But please note that this method does not do any check if the numbers are put properly, so if there are for example letters or special characters in the input, you might get unexpected behavior.
Let's see what you wrote:
int main () {
char values;
std::cout << "Enter , seperated values :";
std::cin >> values; // read a single character
int myints[] = {values}; // create a static array of size 1 containing the single character converted to an int
/* other function same */
}
what you need is:
#include <sstream>
#include <string>
...
int main () {
std::cout << "Enter space seperated values :";
std::vector<int> myvector;
std::string line;
std::getline(std::cin, line); // read characters until end of line into the string
std::istringstream iss(line); // creates an input string stream to parse the line
while(iss >> value) // so long as values can be parsed
myvector.push_back(value); // append the parsed value to the vector
/* other function same */
}
If you want comma separated input you'll need to parse the comma as a single character in addition to the integer values.
What you are doing
int main () {
char values; //Declare space for one character
std::cout << "Enter , seperated values :"; //Ask user to enter a value
std::cin >> values; //Read into values (one value only)
int myints[] = {values}; // assign the first element to the ASCII code of whatever user typed.
/* other function same */
}
In the language char works as an 8-bit integer. Through function overloading, different behavior can be implemented. Read about static polymorphism for more details how it works.
What you need to do
std::vector<int> values;
char ch_in;
std::string temp;
while(cin.get(ch_in)) {
switch(ch_in) {
case ',':
case ' ': //Fall through
values.push_back(atoi(temp.c_str()); //include cstdlib for atoi
temp.clear();
break;
default:
temp+=ch_in;
}
}
You should put this in a separate function. With this skeleton, you can implement a more fancy syntax by adding more cases, but then you need something else than a std::vector<int> to put things into. You can (should?) also add error checking in the default case:
default:
if( (ch_in>='0' && ch_in<='9')
|| (temp.size()==0 && ch_in=='-') ) {
temp+=ch_in;
}
else {
cerr<<ch_in<<" is an illegal character here."
temp.clear();
}
#include <iostream>
#include <string>
#include <sstream>
#include <string.h>
using namespace std;
// THIS CODE IS TO GIVE ARRAY IN ONE LINE AND OF DESIRED LENGHT ALSO WITH NEGATIVE NUMBERS
// You can also do it by using ASCII but we Are using library name
// <sstream> to convert string charters to numbers
//O(n) time complexity
int main()
{
/*
// INPUT
// 7 array length
// 34-56-789 // without space b/w them */
int N;
cout << "Enter the size of the array " << endl;
cin >> N;
cout << "INPUT Without giving space b/w " << endl;
string strx;
cin >> strx;
int X[N]; // array to store num
int p = 0;
// NOTE USE HERE STRX.LENGHT() becouse we have to go through the whole string
for (int i = 0; i < strx.length(); i++)
{ // we have declare tempx to store a particular character
// one time
string tempx;
tempx = strx[i];
stringstream strtointx(tempx);
// this is the syntax to convert char to int using <sstream>
if (strx[i] == '-')
{
/*
The tricky point is when you give string as 1-23
here - and 2 are the separte characters so we are not
getting -2 as number but - and 2 so what we do is
we chek for '-' sign as the character next to it
will be treated as negative number
*/
tempx = strx[i + 1];
// by assigning strx[i+1] to tempx so that we can getting the which should be treated as negative number
stringstream strtointx(tempx);
// still it is a charter type now again using library
// convert it to int type
strtointx >> X[p];
X[p] = -X[p];
// now make that number to negative ones as we want it to be negative
i++;
// inside this if i++ will help you to skip the next charcter of string
// so you can get desired output
}
// now for all the positive ones to int type
else{ strtointx >> X[p]; }
p++; // finally increment p by 1 outside if and else block
}
// loop ends now get your desired output
cout<<"OUTPUT "<<endl;
for (int i = 0; i < N; i++)
{
cout << X[i] << " ";
}
cout<<endl;
cout<<"CODE BY MUKUL RANA NIT SGR Bch(2020)";
return 0;
}
// OUTPUT
/*
Enter the size of the array
7
INPUT Without giving space b/w
34-56-789
OUTPUT
3 4 -5 6 -7 8 9
CODE BY MUKUL RANA NIT SGR Bch(2020)
PS C:\Users\user\Desktop\study c++>
*/
// CAUTION :
/*
1) do not give input with spaces
**** if you do then first you have to change /chek the code for spaces indexes also ***
2)do not give charates as 56-89##13 as you want here only numbers
3) this only for integer if you want to float or double you have to do some changes here
because charters index and length would be difeerent in string.
*/

How to seperate integers from input string and convert them to type int to allow calculations on them

As Mehdi Algholipour wrote i wanted to
1.Get string from input
2.Separate input to Integer numbers
3.Save them into Array
cout << "Give me some integers separated with space";
cin >> string; // example input 10 210 300 510
//..some code that seperate input to integer numbers and save them to Array
//EXPECTED RESULT: Array[0]=10 Array[1]=210 etc...
I think your mean is:
Get string from input
Separate input to Integer numbers
Save them into Array
If this is your mean, try this code:
string str;
int arr[1000]; // I supposed 1000 is your Int Array size.
int number = 0, index = 0;
getline(cin, str); // Get a line of string
for (int i = 0 ; i < str.length() ; i++){ // Processing your str Array
if (isdigit(str[i])){
number *= 10;
number += ((int)str[i] - '0');
}
else {
arr[index++] = number;
number = 0;
}
}
arr[index] = number; // for last element of your input
// Do something you want
Try:
#include <iostream>
#include <string>
#include <vector>
#include <regex>
int main()
{
std::regex rgx("\\b\\d+\\b");
std::string line;
std::cout << "Please enter numbers separated by spaces and press enter:" << std::endl;
std::getline(std::cin, line);
std::sregex_iterator it(line.begin(), line.end(), rgx);
std::sregex_iterator end;
std::vector<int> values;
std::transform(it, end, std::back_inserter(values), [](std::smatch s){ return std::stoi(s.str()); });
for (int v : values)
std::cout << v << std::endl;
}
Use stringstream:
string str;
getline(cin, str);
stringstream ss(str);
vector<int> vec;
int Integer;
while(true)
{
ss >> Integer;
if(!ss)
break;
vec.push_back(Integer);
}
live demo
Note: You need to include following headers: <string>, <sstream>, <vector>

How to read in user entered comma separated integers?

I'm writing a program that prompts the user for:
Size of array
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
}
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.
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.
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.
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;
}
#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;
}
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;
#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
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;
}
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 << " ";
}

Reading in unknown length of numbers

I have an input file that contains some data in coordinate mode
For example (2,3,5) translates to column 2, row 3, and level 5. I'm curious on a method of reading in the numbers after using getline(cin,string) to obtain the data. I don't know how many digits are in the data points so i can't assume the 1st character will be of length 1. Is there any libraries that can help solve the problem faster?
my gameplan so far that's not finished
void findNum(string *s){
int i;
int beginning =0;
bool foundBegin=0;
int end=0;
bool foundEnd=0
while(*s){
if(isNum(s)){//function that returns true if its a digit
if(!foundBegin){
foundBegin=1;
beginning=i;
}
}
if(foundBegin==1){
end=i;
foundBegin=0;
}
i++;
}
}
Try this:
#include <iostream>
#include <cstdlib>
#include <sstream>
#include <vector>
#include <string>
int main() {
std::vector <std::string> params;
std::string str;
std::cout << "Enter the parameter string: " << std::endl;
std::getline(cin, str);//use getline instead of cin here because you want to capture all the input which may or may not be whitespace delimited.
std::istringstream iss(str);
std::string temp;
while (std::getline(iss, temp, ',')) {
params.push_back(temp);
}
for (std::vector<std::string>::const_iterator it=params.begin(); it != params.end(); ++it) {
std::cout << *it << std::endl;
}
return 0;
}
The only caveat is that the arguments will have to be non whitespace delimited.
Example input string:
1,2,3
Output:
1
2
3
Once these arguments have been parsed, you can then convert them from strings to (example) integer via the following:
template <typename T>
T convertToType(const std::string &stringType) {
std::stringstream iss(stringType);
T rtn;
return iss >> rtn ? rtn : 0;
}
which can be used as follows:
int result = convertToType<int>("1");//which will assign result to a value of 1.
UPDATE:
This now works correctly on whitespace delimited input (except for newlines) like the following:
1 , 2, 3 , 4
Which yields:
1
2
3
4
jrd1's answer is pretty good, but if you'd prefer there happen to be functions for converting characters to integers (and back) already in the C standard library (cstdlib). You'd be looking for atoi.
http://en.cppreference.com/w/cpp/string/byte/atoi
#include <sstream>
void findNums(const string &str, int &i, int &j, int &k)
{
std::stringstream ss(str);
char c;
ss >> c >> i >> c >> j >> c >> k;
}
Simply use extractor operator for reading any type of value in respective variable type.
#incude<ifstream> // for reading from file
#include<iostream>
using namespace std;
int main()
{
int number;
ifstream fin ("YouFileName", std::ifstream::in);
fin >> number; // put next INT no matter how much digit it have in number
while(!fin.eof())
{
cout << number << endl;
fin >> number; // put next INT no matter how much digit it have in number and it will ignore all non-numeric characters between two numbers as well.
}
fin.close();
return 0;
}
Have a look over here for more details.
Note: Be careful while using it for character arrays and strings.. :)