Reputation: 101
I need to end the input loop by hitting the enter key. Tried to find something, and I got some guy here saying that this code below will work, sadly it doesn't. What's wrong?
#include <iostream>
#include <sstream>
using namespace std;
int main() {
int a = 0, h = 0, i=0;
string line;
int *tab=new int;
while (getline(cin, line) && line.length() > 0) // line not empty
{
stringstream linestr(line);
while (linestr >> a)// recommend better checking here. Look up std::strtol
{
tab[i]=a;
}
i++;
}
return 0;
}
Go it, thanks!
Here's the code:
#include <iostream>
#include <sstream>
using namespace std;
int main() {
int a = 0, i=0;
string line;
getline(cin, line);
stringstream linestr(line);
int *tab = new int[line.size()/2+1];
while ( linestr >> a )
{
tab[i]=a;
i++;
}
for(int j=0; j<i; j++) cout<<tab[j]<<" ";
return 0;
}
Upvotes: 0
Views: 282
Reputation: 73446
The problem
In your code, you have an allocation problem, since you allocate a single integer for tab. So as soon as you have read the first number, you go out of bounds. This is undefined behavior.
In addition, your outer while is designed to loop until an empty line is entered, with no numbers.
The solution
If your concern is to read a couple of numbers on a single line, then there's no need for a loop:
getline(cin, line);
stringstream linestr(line);
vector<int> tab;
while ( linestr >> a )
{
tab.push_back(a);
}
This approach uses a vector. This has the advantage that you don't need to know how much numbers you'll have in the end. Afterwards, you can find out the size of the vector with tab.size()
and you can access single elements exactly as you would for an array.
Other solution (suboptimal)
If it's for school an you're not allowed to use vector, you can go for a suboptimal substitute:
int *tab = new int[line.size()/2+1];
This makes an estimate of the maximum number of numbers that could potentially be in the string (you'll certainly have less).
Upvotes: 2
Reputation: 206667
The problem in your code is that you have allocated enough space to hold one int
in
int *tab=new int;
and are using tab
as though it can hold as many int
s as you need.
If you are allowed to use std::vector
, change the above line to:
std::vector<int> tab;
and use
while (getline(cin, line) && line.length() > 0) // line not empty
{
stringstream linestr(line);
while (linestr >> a)
{
tab.push_back(a);
}
}
If you are not allowed to use std::vector
, you'll have to figure out how to deal with the dynamic nature of tab
. As a quick work around, you can use a statically defined array and stop reading as soon as you have used up the capacity of the array.
int const MAX_ELEMENTS = 100;
int tab[MAX_ELEMENTS];
...
while (getline(cin, line) && line.length() > 0 && i < MAX_ELEMENTS)
{
stringstream linestr(line);
while (linestr >> a)
{
tab[i] = a;
++i; // Needs to be here not outside this loop.
}
}
Upvotes: 1
Reputation: 6750
One way to do it is the following, which reads numbers in that are separated by spaces and puts them in a vector.
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
int main() {
std::string line;
std::vector<int> v;
std::getline(std::cin, line);
std::stringstream sstream(line);
int i;
while (sstream >> i) {
v.push_back(i);
}
// Check your input vector.
/*
for(auto i : v){
std::cout << i << std::endl;
}
*/
}
Example input:
32 22 62 723765 26 62 72 7 -5 7 2 7 152 62 6 262 72
Upvotes: 1