3

I am overloading stream extraction operator, so that it can be used in Complex class, which i created. When i use cin to input one complex number from user in the from(x,y), it works fine. Note that i am ignoring these characters "(,)". As i only want the numbers.

But when i try to input two numbers from the user in the same format, the program returns (0,0) as the answer, no matter what value is entered. Looks like program fails to ignore those characters, in this case.I am unable to find a way to solve this. Here are the files.

Please take a look at the main.cpp and the output carefully. I entered values like this,

(2,3)
(5,6)

How can i edit this code so that it works fine even when one complex number is entered or more are entered?

Complex.h

#pragma once
#include <iostream>
using namespace std;
#ifndef COMPLEX_H
#define COMPLEX_H

class Complex {
public:

    // constructors
    Complex(double, double);
    Complex(double);
    Complex();

    friend ostream & operator<<(ostream &,Complex &);
    friend istream & operator>>(istream &, Complex &);

private:

    double r;
    double i;
};

#endif

Complex.cpp

#include <iostream>
using namespace std;
#include "Complex.h"


Complex::Complex(double _r, double _i){
    r=_r;
    i=_i;
}

Complex::Complex(double _r){
    r=_r;
    i=0.0;
}

Complex::Complex(){
    r=0.0;
    i=0.0;
}

// Code for overloading stream insertion operator.
ostream& operator<<(ostream& os, Complex& value){
    os << "(" << value.r <<", " << value.i << ")" ;
    return os;
}

 // Code for overloading stream extraction operator.
istream & operator>>(istream& is, Complex& val){
    is.ignore();
    is >>val.r;
    is.ignore();
    is >>val.i;
    return is;
}

main.cpp

#include <iostream>
#include "Complex.h"
using namespace std;

int main(){

    Complex x,y;
    cout<<"Enter complex number in the form(x,y): "<<endl;
    cin>>x>>y;

    cout<<"\nThe 1st complex number entered was "<<x<<endl;
    cout<<"\nThe 2nd complex number entered was "<<y<<endl;

} 

Output

The 1st complex number entered was (2,3)

The second complex number entered was (0,0)

Community
  • 1
  • 1
user3834119
  • 411
  • 9
  • 21
  • Nothing related to your problem (see my answer for that), but you do not need `#pragma once` and your `#ifndef ...`, they both serve the same purpose, so only one is sufficient. – Holt Jul 13 '14 at 12:08
  • I think this answer to a similar question should be very useful : http://stackoverflow.com/a/14331519/3723423 – Christophe Jul 13 '14 at 12:30

2 Answers2

3

@Holt is right, the first ignore() call in the second call to operator>>() is discarding the residual newline character from the previous input. If the character had been cleared beforehand (possibly by clearing the whitespace before returning from the function or when entering) it would have worked.

A more intuitive approach would be to write your own skip<> function template that clears whitespace first and subsequently discards the character you provide if present. A typical implementation looks like this:

template<char n>
std::istream& skip(std::istream& is)
{
    if ((is >> std::ws).peek() != n)
        is.setstate(std::ios_base::failbit);
    else
        return is.ignore();
    return is;
}

You can use it in your extractor like this:

std::istream& operator>>(std::istream& is, Complex& val) {
    is >> skip<'('> >> val.r >> skip<','> >> val.i >> skip<')'>;
    return is;
}
David G
  • 94,763
  • 41
  • 167
  • 253
1

std::istream::ignore will ignore n characters from the stream (1 by default). In your case, the next ignored character is the \n character (newline character), so the next instruction try to read a double from ( which obvisouly fails, hence the value of val.r and val.i is not changed and stay 0.0.

Holt
  • 36,600
  • 7
  • 92
  • 139