0

I have the following class:

class ComplexNumber
{
    public:
        ComplexNumber();
        ComplexNumber(const float &RealPart, const float &ImaginaryPart);
        ComplexNumber(const ComplexNumber &NewComplexNumber);
        ~ComplexNumber(); // useless
        void SetRealPart(const float &RealPart);
        void SetImaginaryPart(const float &ImaginaryPart);
        friend ComplexNumber operator+(const ComplexNumber &Complex1, const ComplexNumber &Complex2);
        friend ComplexNumber operator-(const ComplexNumber &Complex1, const ComplexNumber &Complex2);
        friend std::ostream & operator<<(std::ostream &output, const ComplexNumber &NumberToDsiplay);
        friend std::istream & operator >>(std::istream &input, ComplexNumber &NumberToInput);
        bool operator==(const ComplexNumber &Complex) const;
        bool operator!=(const ComplexNumber &Complex) const;

    private:
        float RealPart;
        float ImaginaryPart;
};

My question is about this operator overloaded: friend std::istream & operator >>(std::istream &input, ComplexNumber &NumberToInput);

Here is the implementation:

std::istream & operator >>(std::istream &input, ComplexNumber &NumberToInput)
{
    std::cout << "Enter the real part: ";
    input >> NumberToInput.RealPart;
    std::cout << "Enter the imaginary part: ";
    input >> NumberToInput.ImaginaryPart;
}

If, instead of input a float, I input a string or whatever type, I get a weird behaviour.

How can I handle that?

How can I handle that with templates?

  • Check `input` (error) status? – Jarod42 Dec 20 '19 at 19:00
  • 2
    Not an answer to your question, but `operator>>` should **not** output anything. – ChrisMM Dec 20 '19 at 19:00
  • @Jarod42 yes, I would like to know if there is a way of handlin the input error –  Dec 20 '19 at 19:02
  • @ChrisMM I didn't know that. Thanks for have said it to me –  Dec 20 '19 at 19:03
  • [basic_istream's doc](https://en.cppreference.com/w/cpp/io/basic_istream): `fail()` – Jarod42 Dec 20 '19 at 19:05
  • 4
    A solution to "handle that" has nothing to do with templates. You need to use an approach to check input, and discard invalid input (e.g. characters that don't make sense to enter a floating point value). This often means not reading directly from the stream using `operator>>()` - for example, reading input as a string, checking the string, discarding bad characters, and then parsing. Also,, the point of these operators is single-purpose - an `operator>>()` to read input from a stream should not also write data to another stream (like `std::cout`). – Peter Dec 20 '19 at 19:21

1 Answers1

3

If, instead of input a float, I input a string or whatever type, I get a weird behaviour.

You want to handle erroneous input:

std::istream& operator>>(std::istream& input, ComplexNumber& NumberToInput)
{
    while (std::cout << "Enter the real part: " &&
        !(input >> NumberToInput.RealPart))
    {
        input.clear();
        input.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        std::cerr << "Bad input, try again.\n";
    }

    while (std::cout << "Enter the imaginary part: " &&
        !(input >> NumberToInput.ImaginaryPart))
    {
        input.clear();
        input.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        std::cerr << "Bad input, try again.\n";
    }
    return input;
} 

input.operator>>(std::istream&, float) will return false if the input was problematic, true otherwise.

Paul Evans
  • 27,315
  • 3
  • 37
  • 54
  • But what if I have to deal with templates? I will edit my question –  Dec 20 '19 at 19:15
  • 1
    Besides printing "try again", you should ignore the rest of erroneous input, as `std::istream::operator>>` leaves it in the buffer if it doesn't manage to parse it, so, at the next try, it'll find it there where it was left, erroring again. – Matteo Italia Dec 20 '19 at 20:36
  • No need to actually read it into an `std::string` after the fact - you can just use [`input.ignore(std::numeric_limits::max(), '\n');`](https://stackoverflow.com/questions/25020129/cin-ignorenumeric-limitsstreamsizemax-n) – Matteo Italia Dec 20 '19 at 21:56
  • @MatteoItalia Oh, that's awesome - thanks again! :-) – Paul Evans Dec 20 '19 at 21:59