【问题标题】:Overloading stream extraction operator in c++在 C++ 中重载流提取运算符
【发布时间】:2014-07-13 11:57:39
【问题描述】:

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

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

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

(2,3)
(5,6)

如何编辑此代码以使其即使在输入一个或多个复数时也能正常工作?

复杂.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

复杂的.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)

【问题讨论】:

  • 与您的问题无关(请参阅我的回答),但您不需要#pragma once 和您的#ifndef ...,它们的用途相同,因此只需一个就足够了。跨度>
  • 我认为对类似问题的回答应该非常有用:stackoverflow.com/a/14331519/3723423

标签: c++ operator-overloading


【解决方案1】:

@Holt 是对的,第二次调用operator&gt;&gt;() 中的第一个ignore() 调用正在丢弃前一个输入中的剩余换行符。如果事先清除了字符(可能是在从函数返回之前或进入时清除空格),它会起作用。

更直观的方法是编写您自己的 skip&lt;&gt; 函数模板,该模板首先清除空格,然后丢弃您提供的字符(如果存在)。典型的实现如下所示:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-10
      • 1970-01-01
      • 2012-09-19
      • 1970-01-01
      • 1970-01-01
      • 2021-04-24
      相关资源
      最近更新 更多