CubSqared
CubSqared

Reputation: 195

Overload ifstream in c++

I am trying to read complex numbers of the form x + y*i from a file which looks like this:

2 + 3i

4 + 5i

If I implement it like this it only works for the first line and I would like to be able to read again in the same manner the second line. Any ideas?

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

Upvotes: 0

Views: 1502

Answers (4)

Yongwei Wu
Yongwei Wu

Reputation: 5582

EDIT: Do not throw exceptions directly, as this is not the usual way of doing thing with iostreams.

EDIT: Process the sign character separately so that spaces in the input are allowed.

A quick and dirty solution:

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

Upvotes: 2

user2249683
user2249683

Reputation:

This should work for you:

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

Note: The space before the imaginary part and the trailing i are breaking the input.

Upvotes: 0

Chnossos
Chnossos

Reputation: 10456

I would do it like this :

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

Upvotes: 0

Peter R
Peter R

Reputation: 2985

You need to make sure that you read both the "+" and the "i" when processing the input.

The following implementation works:

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

Upvotes: 0

Related Questions