1

As I am very new to exceptions, I am having some trouble with the below memory exception code. Basically, I would need to calculate and show sum of 10 positive inputs. During the input, my program should use exception mechanism to display a message that it doesn't allow negative numbers / not-a-numbers (NaN) if so is the input and then exit the program. I am told to use std::cin.fail() to detect whether the value entered fits the variable type(but I am not sure how to implement it). Would appreciate your help thanks!

#include <iostream>

int main() {
    int number;
    int a=-2;
try {

    for(int i=0; i<10;i++) {
    std::cin>>number;

    }
}
catch (...) {

    number==-number?
      std::cout << "Its negative"<<std::endl; 

    number==a? 
      std::cout << "Its NaN"<<std::endl; 
    }
}
  • 1
    the stream itself can be tested as a boolean to see if a read failed. eg: `if (std::cin>>number) { test number for negative/NaN and throw exception if true } else { didn't get a number at all. Throw exception }` – user4581301 Mar 07 '19 at 07:51
  • Hi @user4581301, how do I test for NaN? Thanks for ur input. –  Mar 07 '19 at 07:54
  • If your compiler is reasonably recent (Supports C++11), you can use the aptly named [`isnan`](https://en.cppreference.com/w/cpp/numeric/math/isnan). If not, [it gets ugly](https://stackoverflow.com/questions/570669/checking-if-a-double-or-float-is-nan-in-c). – user4581301 Mar 07 '19 at 08:02

1 Answers1

0

You say "10 positive inputs", but you have int number;. If your number is going to be an integer, then it can't take fractions like 33.44 for instance, and it also can't be NaN (so you wouldn't need to check for that). If you want to allow fractions, do double number instead. That aside, the check could look like this:

for (int i = 0; i < 10; i++) {
        std::cin >> number;
        if (std::cin.fail()) {
            std::cin.clear();
            std::string input;
            std::cin >> input;
            std::cout << "input failed! Invalid input: " << input << std::endl;
            return -1;
        }

After every inputted number, you do the std::cin.fail() check. If it failed, you can just return. In this example, I also made it print the invalid input. For that you need to call std::cin.clear(); to reset that error flag, and then you can put that invalid input into an std::string (which should work, unlike with the number). You need to include <string> for that. If you don't need to print anything, you can just return and forget about the clearing, the string and the output. Also, in this example, since the mess made by the invalid input is neatly cleaned up, you could take more (valid) inputs again if you don't return instead.

Next, checking for negative numbers:

if (number < 0) {
    std::cout << "Error: Negative number!" << std::endl;
    return -1;
}

Finally, the NaN check (for double):

if (isnan(number)) {
    std::cout << "Error: number is NaN!" << std::endl;
    return -1;
}

You need to include <math.h> for the isnan.

Putting it all together, it could look like this:

#include <iostream>
#include <string> // std::istream >> std::string
#include <math.h> // isnan

int main() {
    double number;

    for (int i = 0; i < 10; i++) {
        std::cin >> number;
        if (std::cin.fail()) {
            std::cin.clear();
            std::string input;
            std::cin >> input;
            std::cout << "input failed! Invalid input: " << input << std::endl;
            return -1;
        }
        if (number < 0) {
            std::cout << "Error: Negative number!" << std::endl;
            return -1;
        }
        if (isnan(number)) {
            std::cout << "Error: number is NaN!" << std::endl;
            return -1;
        }
    }
    return 0;
}
Blaze
  • 16,736
  • 2
  • 25
  • 44