2

I'm trying to learn C++ as my first language and I want to apologies for my silly question. I want to fill two vectors with integers and display their sizes, but every time when check their number of elements I receive unexpected results.Perhaps I'm missing something fundamental.Here is my code:

`

#include<vector>
#include<string>
#include<iostream>

using namespace std;

int main(int argc, char** argv) {

    string stop;
    vector <int>adults;
    vector <int>kids;
    int  int_var;


    while (getline(cin, stop) && stop != "stop") {

        cin>>int_var;


        if (int_var > 16) {
            adults.push_back(int_var);

        } 
         else if (int_var <= 16) {
            kids.push_back(int_var);
        }

    }
    cout << "Number of adults: " << adults.size() << endl;
    cout << "Number of kids: " << kids.size() << endl;



}

`

Every time in this crappy code the first value of int_var goes to second vector where must contain only numbers >16 .I'd be grateful if someone tells me where I'm wrong.

odido
  • 21
  • 2
  • You are probably going wrong by not using a debugger. Using a debugger will give you a better understanding of how your program actually works. – Thomas Matthews Jan 24 '19 at 21:25
  • 3
    Can you show what input you are using? Also: https://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction – NathanOliver Jan 24 '19 at 21:26
  • 2
    BTW, you don't need the `if` in the `else` statement. The opposite condition of `>` is `<=`. – Thomas Matthews Jan 24 '19 at 21:26
  • 1
    Working with **"appropriate"** input [Demo](https://ideone.com/6dJCKO) – Jarod42 Jan 24 '19 at 21:29
  • 3
    I'd replace `cin>>int_var;` with `int_var = stoi(stop);`. – Fred Larson Jan 24 '19 at 21:31
  • Fair enough ,here some examples: When I input random numbers for example : 20 and 30 The correct output must be adults.size(2) ,but first value goes to vector kids instead. – odido Jan 24 '19 at 21:34
  • 3
    You are reading a line to see if the user wants to continue, then you are reading in the next line as a number, then you read a line to see if the user wants to continue, then another number, etc. So the first number you input will be ignored, as it just checks if it says 'stop' or not (that's what the getline in the loop is doing). – Blam Jan 24 '19 at 21:41
  • @NathanOliver this link seems very interesting and perhaps this is the issue 10x Fred Larson good point! – odido Jan 24 '19 at 21:45
  • @odido Looks like you got a good course on C++! There ain't that many around. – JVApen Jan 24 '19 at 21:47
  • @Blam Then how can I pass first number to the if statements after getline()checks the value ? – odido Jan 24 '19 at 21:50
  • 1
    Consider filling "std::stringstream ss" with your proposed test sequence. i.e. "ss << 10 20 " -- note that the whole line is consumed by getline(...). Note that the get line is called after each integer ,,, plan an input sequence, then test your code until it works. – 2785528 Jan 24 '19 at 21:54

2 Answers2

2

I recommend the following strategy.

  1. Read the contents of the file/cin line by line in a loop.
  2. If the line contains the instructions to stop, stop the loop.
  3. Extract the necessary data from the line by using a std::istringstream.
  4. If there is an error in extracting the data, deal with the error. Otherwise, use the data.

std::string line;
while (getline(std::cin, line) )
{
   if ( line == "stop")
   {
      break;
   }

   std::istringstream str(line);

   if ( str >> int_var )
   {
      // Data extraction was successful. Use the data
      if (int_var > 16)
      {
         adults.push_back(int_var);
      } 
      else if (int_var <= 16)
      {
         kids.push_back(int_var);
      }
   }
   else 
   {
      // Error extracting the data. Deal with the error.
      // You can choose to ignore the input or exit with failure.
   }
}
R Sahu
  • 196,807
  • 13
  • 136
  • 247
0

Here's an alternate solution using std::stoi, as my comment suggested:

#include<vector>
#include<string>
#include<iostream>

int main(/*int argc, char** argv*/)
{

    std::string entry;
    std::vector<int> adults;
    std::vector<int> kids;
    int int_var;

    while (std::getline(std::cin, entry) && entry != "stop")
    {
        try
        {
            int_var = std::stoi(entry);

            if (int_var > 16)
            {
                adults.push_back(int_var);

            }
            else
            {
                kids.push_back(int_var);
            }
        }
        catch (const std::exception& /*ex*/)
        {
            std::cout << "Oops, that wasn't a valid number. Try again.\n";
        }
    }

    std::cout << "Number of adults: " << adults.size() << '\n';
    std::cout << "Number of kids: " << kids.size() << '\n';
}
Fred Larson
  • 56,061
  • 15
  • 106
  • 157