c++中重载流提取操作符

Overloading stream extraction operator in c++

本文关键字:提取 操作符 重载 c++      更新时间:2023-10-16

我正在重载流提取操作符,以便它可以在我创建的复杂类中使用。当我使用cin在from(x,y)中输入一个来自用户的复数时,它工作得很好。注意,我忽略了这些字符"(,)"。因为我只想要数字。

但是当我尝试以相同的格式输入用户的两个数字时,无论输入什么值,程序都会返回(0,0)作为答案。在这种情况下,看起来程序没有忽略这些字符。我找不到解决这个问题的方法。这些是文件。

请仔细查看main.cpp和输出。我输入的值是这样的

(2,3)
(5,6)

我如何编辑此代码,使其工作良好,即使一个复数输入或多个输入?

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;
} 

输出

输入的第一个复数为(2,3)

第二个输入的复数为(0,0)

@Holt是正确的,第二次调用operator>>()时,第一个ignore()调用丢弃了之前输入的剩余换行符。如果事先清除了该字符(可能是在从函数返回之前或输入时清除空白),则可以正常工作。

更直观的方法是编写自己的skip<>函数模板,首先清除空白,然后丢弃您提供的字符(如果存在)。典型的实现是这样的:

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;
}

您可以在提取器中这样使用它:

std::istream& operator>>(std::istream& is, Complex& val) {
    is >> skip<'('> >> val.r >> skip<','> >> val.i >> skip<')'>;
    return is;
}

std::istream::ignore将忽略流中的n字符(默认为1)。在您的情况下,下一个被忽略的字符是n字符(换行字符),因此下一个指令尝试从(中读取double,这显然失败了,因此val.rval.i的值没有改变,并保持0.0