Boost logo

Boost Users :

Subject: [Boost-users] [boost-users] istream_iterator question
From: Max (more4less_at_[hidden])
Date: 2009-05-09 10:07:43


Hello,

I don't know why the following code does not work as expected.
I hope the guru's here could lend me a hand.

For a test data file:
3
1 2
3 4
5 6

2
1.2 4.3 234.2
3.5656 67.88 345.3
<eof>

and 2 simple test helper class:

struct a
{ int i, j; };
std::istream& operator>>(std::istream& in, a & p)
{ in >> p.i >> p.j; return in; }
std::ostream& operator<<(std::ostream& out, const a & p)
{ out << p.i << " " << p.j; return out; }

struct b
{ float i, j, k; };
std::istream& operator>>(std::istream& in, b & p)
{ in >> p.i >> p.j >> p.k; return in; }
std::ostream& operator<<(std::ostream& out, const b & p)
{ out << p.i << " " << p.j << " " << p.k; return out; }

Here is version 1, quite trivial and works just ok.

                std::ifstream is("./test.txt")
                int n;
                is >> n;
                std::cout << "n=" << n << "\n";
                for(int i=0; i<n; i++)
                {
                        a tmp;
                        is >> tmp;
                        va.push_back(tmp);
                }
                std::copy(va.begin(), va.end(),
std::ostream_iterator<a>(std::cout, "\n"));
                is >> n;
                std::cout << "n=" << n << "\n";
                for(int i=0; i<n; i++)
                {
                        b tmp;
                        is >> tmp;
                        vb.push_back(tmp);
                }
                std::copy(vb.begin(), vb.end(),
std::ostream_iterator<b>(std::cout, "\n"));

The output is:
n=3
1 2
3 4
5 6
n=2
1.2 4.3 234.2
3.5656 67.88 345.3

With version 2 using istream_iterator, the behavior is strange:

                is >> n;
                std::cout << "n=" << n << "\n";
                std::copy_n(std::istream_iterator<a>(is),
                        std::istream_iterator<a>(), n,
std::back_inserter(va));
                std::copy(va.begin(), va.end(),
std::ostream_iterator<a>(std::cout, "\n"));
                is >> n;
                std::cout << "n=" << n << "\n";
                std::copy_n(std::istream_iterator<b>(is),
                        std::istream_iterator<b>(), n,
std::back_inserter(vb));
                std::copy(vb.begin(), vb.end(),
std::ostream_iterator<b>(std::cout, "\n"));

copy_n is defined as:

template <class InputIterator, class Size, class OutputIterator>
        OutputIterator copy_n( InputIterator first, InputIterator last,
        Size n,
        OutputIterator result)
{
        // copies the first `n' items from `first' to `result'. Returns
        // the value of `result' after inserting the `n' items.
        // it ends before n iterations, if the last iterator is reached
        while( n-- && first != last)
        {
                *result = *first;
                ++first;
                ++result;
        }
        return result;
}

The output is now:
n=3
1 2
3 4
5 6
n=3

I've checked the code for several times and just not found the
answer. I'm using VS2008SP1 on WinXP/SP1

Thanks for your help.

B/Rgds
Max


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net