0

I have been trying to create a simple while loop to cin numbers into a vector, with some basic input validation. However, I am finding some weird things happening with my code. I am trying to have it so that the user can input numbers until they type in '0', which will then end the loop. This works fine.

However, I am also trying to make it so that if they enter a non-int (i.e. 3.4, a), or if they enter a negative number, it couts "BAD INPUT" and then quits the program. When I type in a negative number, it works fine. But when I type in a non-int, it does not cout anything, but still quits the program...

Likewise, I am also trying to have it so that if they type in '0' first, without having put in any numbers beforehand, it couts "NO NUMBERS" and quits the program. This one also quits the program, but again, does not cout anything.

My code is as follows:

   #include <iostream>
   #include <vector>

   //I know it is considered bad practice for the below part.
   using namespace std;

   int main() 
   {
        vector<int> numberStorage;

        while (cin) {
            int numInput = 0;

            cin >> numInput;

            if (numInput == 0) break;

            if (!cin || numInput < 0) {
                cout << "BAD INPUT" << '\n';
                return false;
            }

            if (numInput == 0 && numberStorage.size() == 1) {
                cout << "NO NUMBERS" << '\n';
                return false;
            }   
            numberStorage.push_back(numInput);
        }

        return 0;
    }

Can anyone help me and clarify as to where my logic/code is going wrong here on these input validations? Thank you for any help.

Gilson PJ
  • 3,443
  • 3
  • 32
  • 53

4 Answers4

2

Try this:

#include <iostream>
#include <vector>
//I know it is considered bad practice for the below part.
using namespace std;

vector<int> numberStorage;

int main() {
  while (true) {
    int numInput = 0;

    cin >> numInput;

    if (cin.fail() || numInput < 0) {
      cout << "BAD INPUT" << '\n';
      break;
    }

    if (numInput == 0) {
      cout << "Received 0" << endl;
      break;
    }

    if (numInput == 0 && numberStorage.size() == 1) {
      cout << "NO NUMBERS" << '\n';
      return false;
    }   
    numberStorage.push_back(numInput);
  }

  return 0;
}

In the original code, you were not checking for cin.fail(). When you were trying to store a value that was not an int inside numInput, the cin was silently failing and as you initialized numInput to 0, it was exiting the loop as if the client had entered the number zero on console.

You can check that yourself by adding a cout on the zero value condition of the original code.

cheers

rcmgleite
  • 1,303
  • 1
  • 18
  • 22
  • Thank you, rcmgleite! That did it. I appreciate the concise answer, and the explanation to where I went wrong. –  Oct 06 '18 at 20:31
2

When cin fails, it will assign value 0 to numInput and your logic

if (numInput == 0) break;

silently exiting the program.

Gilson PJ
  • 3,443
  • 3
  • 32
  • 53
  • this is actually the correct answer. i also thought that `while(cin)` would cause the problem but thats not the case. – Yucel_K Oct 06 '18 at 20:31
  • That makes a lot of sense. I am surprised I was not able to see that (I am a beginner!) Thanks. –  Oct 06 '18 at 20:32
0

You can check by using cin.fail() just after setting integer for checking not number.

#include <iostream>
#include <vector>
using namespace std;

vector<int> numberStorage;

int main() {
    while (cin) {
        int numInput = 0;

        cout << "Please enter:";
        cin >> numInput;

        if(cin.fail()) {
            cout << "NO NUMBER" << "\n";
        }

        if (numInput == 0) break;

        if (!cin || numInput < 0) {
            cout << "BAD INPUT" << '\n';
            return false;
        }

        numberStorage.push_back(numInput);
    }
}

here is the result : https://onlinegdb.com/SyIWdqU9m

sorabh86
  • 457
  • 4
  • 17
0

It would be a good practice if you call cin.clear() in case cin.fail() occurs in order to clear the error flag on cin, so that future I/O operations will work correctly.

Just a recommendation!

Salar Askar
  • 126
  • 6