0

I am trying to read a line of string characters with numbers (e.g "30 40 50 20") and put them into a vector. I also need to avoid empty space and newlines. But when I read the input, it doesn't see the string "30", it sees the characters "3" and "4".

void Input() {
        getline(cin,line, '\n');
        for (int i = 0; i < line.length(); i++) {
            if (! (isspace(line[i]))) {
                cout << line[i] << ", ";
                    scores.push_back(line[i]);//(atoi(input));
            }
        }
        cout << scores.size() << "! ";
    }

A line like "30 40 50" won't give a vector size of 3, it will give a size of 6. What are the optimal ways to get around this issue?

EDIT: I should have clarified in the original message that this is for a challenge, in which I am unable to include the string stream library in the original case.

Sammieo
  • 155
  • 7

4 Answers4

2

I think you're doing the right thing grabbing the whole line before parsing, otherwise you get into a bit of a pickle. But you do actually have to do some parsing. Right now you're just pulling out individual characters.

The following isn't optimal but it'll get you started — continue using formatted stream extraction, but isolated to this line from the file.

So:

void Input()
{
    getline(cin, line, '\n');
    istringstream ss(line);

    int val;
    while (ss >> val)
      scores.push_back(val);

    cout << scores.size() << "! ";
}
Lightness Races in Orbit
  • 358,771
  • 68
  • 593
  • 989
1

Read the line and put into a std::istringstream, then read as "normally" using the >> operator from the string stream.

Some programmer dude
  • 363,249
  • 31
  • 351
  • 550
  • I know from past challenges that this would work, but the challenge I'm currently doing refuses to let me add a stringstream library; hence, any of the suggestions tried here only fail at compile time. Thanks, though! – Sammieo Jan 08 '16 at 00:19
  • EDIT: my mistake, didn't mean to comment twice. – Sammieo Jan 08 '16 at 00:50
  • @Sammieo Then I suggest you try to [`find`](http://en.cppreference.com/w/cpp/string/basic_string/find) the spaces and then get a [*sub-string*](http://en.cppreference.com/w/cpp/string/basic_string/substr) containing the value. Do it in a loop, and keep track of the start of the next sub-string. – Some programmer dude Jan 08 '16 at 06:56
1

Putting the line into a std::istringstream and extracting the numbers from that is the best way.

Here's an alternative to a manual loop using the standard library:

std::istringstream numbers(line);
std::copy(std::istream_iterator<int>(numbers), 
          std::istream_iterator<int>(),
          std::back_inserter(scores));
molbdnilo
  • 55,783
  • 3
  • 31
  • 71
0

It is probably best to take advantage of an input stringsteam, example: http://www.cplusplus.com/reference/sstream/stringstream/stringstream/.

The extraction operator allows you to parse data from the stream to some variable of datatype T. Another advantage of input stringstreams is the ability to query whether the pass was successful, and in your case ignore whitespace characters by setting the skipws format flag.

Example:

int main () {

  std::istringstream ss("30 40 50");
  float val = 0.0f;

  while( ss >> std::skipws >> val )
  {
      std::cout << val << "\n";
  }

  return 0;
}

Out: 30 40 50

lukemtesta
  • 262
  • 3
  • 10
  • Note: [`eof` is usually a bad idea](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong). And `>> val` already skips leading whitespace. – molbdnilo Jan 07 '16 at 14:37
  • I prefer to explicitly state the whitespace flag - noskipws and skipws – lukemtesta Jan 07 '16 at 14:38
  • I know from past challenges that this would work, but the challenge I'm currently doing refuses to let me add a stringstream library; hence, any of the suggestions tried here only fail at compile time. Thanks, though! – Sammieo Jan 08 '16 at 00:20
  • np hope you get it fixed! – lukemtesta Jan 08 '16 at 10:54