Krystian Niżeniec
Krystian Niżeniec

Reputation: 101

c++ ending loop with 'enter' hit

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

Answers (3)

Christophe
Christophe

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

R Sahu
R Sahu

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 ints 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

Rivasa
Rivasa

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

Related Questions