【问题标题】:Overload ifstream in c++在 C++ 中重载 ifstream
【发布时间】:2014-03-28 11:06:07
【问题描述】:

我正在尝试从如下所示的文件中读取 x + y*i 形式的复数:

2 + 3i

4 + 5i

如果我这样实现它,它只适用于第一行,我希望能够以相同的方式再次读取第二行。有什么想法吗?

istream& operator>>(istream& in, Complex& c) {
    in >>  c.r >> c.i;
    return in;
}

【问题讨论】:

  • 文件格式有优势
  • “+ 3i”是如何解析的:D
  • @DieterLücking 加号被理解为第二个数字的符号,因此可以。问题是最后一个“i”。
  • 老实说,我会使用 getline() 然后在结果行上执行 scanf 以解析您想要的确切格式。

标签: c++ file-io stream operator-overloading


【解决方案1】:

编辑:不要直接抛出异常,因为这不是使用 iostreams 的常用方法。

编辑:单独处理符号字符,以便允许输入中的空格。

快速而肮脏的解决方案:

istream& operator>>(istream& in, Complex& c)
{
    char sign;
    char suffix;
    in >> c.r >> sign >> c.i >> suffix;
    if ((sign != '+' && sign != '-') || suffix != 'i') {
        in.setstate(ios::failbit);
    }
    if (sign == '-') {
        c.i = -c.i;
    }
    return in;
}

【讨论】:

  • 我确实做了类似的事情,但我不是很高兴,因为它不是一般性或指导性的。
【解决方案2】:

您需要确保在处理输入时同时读取“+”和“i”。

以下实现有效:

struct complex
{
    double r;
    double i;
};

std::istream& operator>>(std::istream& in, complex& c)
{
    char plus, i;

    in >> c.r >> plus >> c.i >> i;

    return in;
}

std::string initdata = "2 + 3i\n4 + 5i\n";

int main()
{
    std::stringstream ss(initdata);
    std::vector<complex> values;
    std::istream_iterator<complex> begin(ss), end;

    std::copy(begin, end, std::back_inserter<std::vector<complex>>(values));
}

【讨论】:

  • 您将消除虚部的减号。
  • @YongweiWu 变量plus 应该被称为sign。并且在呈现数据时,符号和虚部之间有一个空格,因此它们必须单独解析 - 它不能是数字的一部分。此代码在发布之前已编译和测试。如果operator&gt;&gt; 中的signi 参数没有正确的值,我要做的唯一其他更改是设置失败位。
  • 哦,我错过了空间问题。我需要更正我的答案来处理这个问题。
【解决方案3】:

我会这样做:

#include <iostream>

struct complex
{
    int r, i;
};

int main ()
{
    complex co;
    char c;

    while ((std::cin >> co.r >> c /* '+' */ >> co.i >> c /* 'i' */))
    {
        std::cout << co.r << ' ' << co.i << "i\n";
    }
}

【讨论】:

    【解决方案4】:

    这应该适合你:

    #include <iostream>
    #include <sstream>
    
    int main(int argc, char *argv[])
    {
        std::istringstream s(
            "2 + 3i\n"
            "4 + 5i\n"
        );
        char sgn;
        double r;
        double i;
        while(s >> r >> sgn >> i) {
            if(s.get() != 'i') {
                std::cerr << "Missing i\n";
                return -1;
            }
            std::cout << r << sgn << i << "i\n";
        }
        return 0;
    }
    

    注意:虚部之前的空格和后面的 i 会破坏输入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-20
      • 1970-01-01
      • 2023-04-03
      • 2010-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多