运算符<<重载不适用于复数

Operator<< Overloading not working right for complex numbers

本文关键字:lt 适用于 重载 运算符 不适用      更新时间:2023-10-16

我有一个编程任务,我必须重载运算符<<(istream,class)方法。

这个想法是您可以在命令控制台中键入一个复数,例如 5.6 + 6.7i 和然后,您可以使用 CIN 获取该数据并将其存储到 ComlexNumber 对象中。辛<<p>这是重载方法

istream & operator>>(istream & in, ComplexNumber & n){
double real;
double imag;
in>>real;
char _operator;
in.get(_operator);
while(_operator == ' ' || _operator == 'n' || _operator == 't'){
    in.get(_operator);
}
int mult;
switch(_operator){
    case '+':
        mult = 1;
        break;
    case '-':
        mult = -1;
        break;
    default :
        in.setstate(ios::failbit);
        return in;              
};
in>>imag;
imag *= mult;   
n = ComplexNumber(real,imag);
return in;
}

问题是,当我尝试使用控制台测试代码时,当我输入复数时,只有数字的实部获得正确的值,虚部始终得到 0。我认为这与我试图解析紧邻"i"字符的数字这一事实有关。奇怪的是,当我将值存储为整数但不存储双精度时,代码工作正常。有谁知道为什么会这样,是否有解决方案?

我必须承认我运行了你的代码并且它有效。我认为您在构造函数(ComplexNumber(double,double))或重载operator =方面存在问题。这是我的测试代码:

#include <iostream>
using namespace std;
class ComplexNumber{
   friend istream & operator>>(istream &in, ComplexNumber &in);
}; 
istream & operator>>(istream & in, ComplexNumber & n){
double real;
double imag;
in>>real;
char _operator;
in.get(_operator);
while(_operator == ' ' || _operator == 'n' || _operator == 't'){
    in.get(_operator);
}
int mult;
switch(_operator){
 case '+':
     mult = 1;
     break;
 case '-':
     mult = -1;
     break;
 default :
     in.setstate(ios::failbit);
     return in;              
};
in>>imag;
imag *= mult;   
cout << real << " " << imag << endl;
return in;
} 
int main(){
   ComplexNumber c;
   cin >> c;
   system("pause");
   return 0;
}

我试过输入:

  • 3.0+2.0i
  • 1-2
  • 1231.1231+234.41i
  • 214 +3.14

尽管您的代码可以简化(并且可能更正为正确的输入运算符),但它实际上应该像它一样工作。它当然对我有用。您的 ComplexNumber 构造函数是否同时设置了realimag部分?

以下是一些建议:

  1. 使用std::ws操纵器可以更轻松地跳过空格:

    in >> std::ws;
    

    当然,如果您只是对_operator使用格式化读取,则可以一次性读取整个值:

    char _operator, i;
    if (in >> real >> _operator >> imag >> i) { ... }
    
  2. 您的代码当前将尾随i保留在流中。相反,它应该读取值并验证是否存在'i'字符。

  3. 您应该在读取始终检查值是否已成功读取!
  4. 一个正确的输入运算符从创建一个sentry对象开始:这个对象刷新一个潜在的tie() d输出流(例如,std::cout tie() d到std::cin),跳过前导空格,并检查流是否良好:

    std::istream::sentry cerberos(in);
    if (cerberos) {
        // the main operation goes here
    }