-8

I have following function within a class, which gets real part of a complex number:

double inputReal(){
        double real;
        cout << "Enter real part: ";
        cin >> real;
        bool compare = typeid(real) == typeid(double);
        while (compare != true){
            cout << "Incorrect input. Try another input: ";
            cin >> real;
        }
        return real;
    }

It should check if real is actually a number and if real isn't a number - it should get another input. However, if I try inputing something like: "aa" or "#@", it skips the while part and proceeds to output, ignoring getting the imaginary part:

double inputImag(){
        double imaginary;
        cout << "Enter imaginary part: ";
        cin >> imaginary;
        bool compare = typeid(imaginary) == typeid(double);
        while (compare != true){
            cout << "Incorrect input. Try another input: ";
            cin >> imaginary;
        }
        return imaginary;
    }

Output, if I try inputing "aa" as a real part:

Enter real part: aa
Enter imaginary part: Absolute value of complex number: 0
Argument of complex value: 0
Program ended with exit code: 0

The code works just fine, if I input correctly, so I suspect it's the comparison of types within those functions. I need to know what did I do wrong and how I can fix it. I'm relatively new to C++ and my college professor requires checking, that user inputs correctly. Feel free to ask anything, if the question seems unclear.

  • 15
    The type of the variable is always the same. It never changes. You can’t use that to check what was input. You need to either take input as text and check conversion, or check that cin actually read something into the variable. – Sami Kuhmonen Apr 06 '23 at 12:30
  • 1
    I'm going to go out on a limb, and predict that using typeid is what came out of ChatGPT when asked how to compare types in C++. Was I right? – Sam Varshavchik Apr 06 '23 at 12:35
  • After `int x;` the expression `typeof(x)` will always be the same as `typeof(int)`. The value of variable `x` is immaterial here, only the type used in its declaration matters. I'd recommend you forget `typeid` exists -- it's very rarely used in practice. Try instead experimenting with code like `if (std::cin >> x) { ... }` to check if the input was successful. – chi Apr 06 '23 at 12:37
  • 3
    C/C++ is a type-safe language, so checking typeid()s in the code results in const expressions to be compared, probably eliminated by the compilers optimizer. The standart behaviour of cin is to read and convert data until a not-matching char is found. So your only chance to get control over this, is to read (as Sami wrote) the text and do the format checking and the conversion separately step by step. – Synopsis Apr 06 '23 at 12:37
  • typeid is something, someone suggested using on StackOverflow. It has nothing to do with ChatGPT. – pineaapplepower Apr 06 '23 at 12:38
  • Your compiler knows that `real` has type `double`. Your own code states as much. Your code is creating a `double` and then checking if it is a `double`. – Drew Dormann Apr 06 '23 at 12:40
  • @pineaapplepower best hint I have here: https://stackoverflow.com/questions/24504582/how-to-test-whether-stringstream-operator-has-parsed-a-bad-type-and-skip-it?r=Saves_AllUserSaves – πάντα ῥεῖ Apr 06 '23 at 12:43
  • 1
    You are confusing *type* with *value*. In some languages (so called weakly typed languages) these are the same or similar. But in strongly typed languages (like C++) they are different. When you declare a variable as a `double` it's type will always be `double`. – john Apr 06 '23 at 12:48
  • Thanks for the answers! It all became clear for me now. – pineaapplepower Apr 06 '23 at 12:51

1 Answers1

0

typeid(real) == typeid(double) will always be true since real is a double.

If you want to check that you have valid input, you need to actually check the input. Here is one way of doing that

double inputReal()
{
    std::size_t end_pos{};
    std::string input;
    std::cout << "Enter real part: ";
    while (getline(std::cin, input))              // get the full line of input
    {
        double real = std::stod(input, &end_pos); // convert to double 
        if (end_pos == input.size())              // check to see if all of the input was converted
            return real;
        else
            std::cout << "Incorrect input. Try another input: ";
    }
}
Lundin
  • 195,001
  • 40
  • 254
  • 396
NathanOliver
  • 171,901
  • 28
  • 288
  • 402