3

演算子のオーバーロードを使用して複素数を実装しています。プログラムでは、ユーザーは常に次の形式で複素数を入力します。

a + bi

では、例えば…

25.0 + 3.6i

ユーザーは常に複素数の実部と虚部の両方を入力すると仮定します。たとえば、ユーザーは「5 + 0i」(「5」ではなく) または「0 - 6.2i」(「-6.2」ではなく) を入力します。私")。

私の問題は、main() に次のコードがあることです。

ComplexNumber c1;
cin >> c1;
cout << c1;

コードは次のように表示されます。

0 + 0i

...実行時にプロンプ​​トに「4.2 + 8.3i」と入力したとき。

これが私のoperator>>クラスの実装です:

istream & operator>>(istream & in, ComplexNumber & n) {
    string real;
    string imag;
    bool done = false;
    int sign = 1;

    string num;
    in >> num;

    int length;
    for (int i = 0; i < num.length(); i++) {
        if (num.at(i) == 'i') {
            imag = num.substr((i - length), i);
        }
        else if (num.at(i) == '-') {
            sign = -1;
        }
        else if (num.at(i) == ' ') {
            if (!done) {
                real = num.substr(i);
                done = true;
            }
            length = 0;
        }
        length++;
    }

    n = ComplexNumber(atof(real.c_str()), atof(imag.c_str()) * sign);
    return in;
}

operator<<クラスの私の実装は次のとおりです。

ostream & operator<<(ostream & out, const ComplexNumber & n) {
    n.print(out);
    return out;
}

以下は、ComplexNumber メンバー クラス print() の実装です。

void ComplexNumber::print(ostream & out) const {
    if (imag >= 0)
        out << real << " + " << imag << "i";
    else 
        out << real << " - " << (-1 * imag) << "i";
}

詳細については、これが私の ComplexNumber ヘッダー ファイルです。

#ifndef COMPLEXNUMBER_H
#define COMPLEXNUMBER_H

#include <iostream>
using namespace std;

class ComplexNumber {

  public:

    // constructors
    ComplexNumber();
    ComplexNumber(double real_part, double imaginary_part);
    ComplexNumber(const ComplexNumber & rhs);

    // named member functions
    void print(ostream & out = cout) const;
    bool equals(const ComplexNumber & rhs) const;

    // assignment operators
    const ComplexNumber & operator=(const ComplexNumber & rhs);
    const ComplexNumber & operator+=(const ComplexNumber & rhs);
    const ComplexNumber & operator-=(const ComplexNumber & rhs);
    const ComplexNumber & operator*=(const ComplexNumber & rhs);

  private:
    double real;      
    double imag; 
};

// arithmetic operators
ComplexNumber operator+(const ComplexNumber & lhs, const ComplexNumber & rhs);
ComplexNumber operator-(const ComplexNumber & lhs, const ComplexNumber & rhs);
ComplexNumber operator*(const ComplexNumber & lhs, const ComplexNumber & rhs);

// relational operators
bool operator==(const ComplexNumber & lhs, const ComplexNumber & rhs);
bool operator!=(const ComplexNumber & lhs, const ComplexNumber & rhs);

// I/O operators
ostream & operator<<(ostream & out, const ComplexNumber & n);
istream & operator>>(istream & in, ComplexNumber & n);

#endif

私の実装に関する助けは素晴らしいでしょう。

4

2 に答える 2

5

基本的に、あなたoperator >>は複雑すぎて、エラーを適切に処理することさえできません。値を最初から文字列に読み込むのではなく、数値に直接読み込んでください。さらに、各読み取り操作の後、ストリームの状態を確認する (場合によっては設定する) 必要があります。

istream& operator >>(istream& in, ComplexNumber& value) {
    int re;
    if (not (in >> re)) {
        return in;

    char pm;
    if (not (in >> pm) or (pm != '+' and pm != '-') {
        in.setstate(ios::failbit);
        return in;
    }

    int im;
    if (not (in >> im))
        return in;

    char i;
    if (not (in >> i) or i != 'i') {
        in.setstate(ios::failbit);
        return in;
    }

    value = ComplexNumber {re, (pm == '-' ? -im : im)};
    return in;
}

(私は怠け者なので、C++11 の初期化子を使用しました ….)

そして、はい、これは、読み取り全体を単一の連鎖式に引き込むことで、さらに短く書くことができます。

istream& operator >>(istream& in, ComplexNumber& value) {
    int re;
    int im;
    char pm;
    char i;

    if (not (in >> re >> pm) or
        (pm != '+' and pm != '-') or
        not (in >> im >> i) or
        i != 'i')
    {
        in.setstate(ios::failbit);
        return in;
    }

    value = ComplexNumber {re, (pm == '-' ? -im : im)};
    return in;
}

これが良いかどうかは、聴衆次第です。個人的には、最初のバージョンより (!) 読みやすいと思います。より構造化された代替手段 (このような単純なケースではやり過ぎです) は、Boost.Qiで、非常にエレガントなパーサーの構築を可能にします。

于 2012-04-25T22:28:56.187 に答える
1

この部分:

string num;
in >> num;

入力から1ワードのみを読み取ります。4.2 + 8.3iのような3つの単語を読むには、何度か呼び出す必要があります。

于 2012-04-25T22:19:17.043 に答える