Click to See Complete Forum and Search --> : Question about input iterator.


George2
February 6th, 2003, 02:35 AM
Hi, everyone!

I am puzzled at some words taken from my STL
tutorial. Here are the words at which I am puzzled.

--------
Note: For two input iterators a and b, a == b implies *a == *b.
For istream iterators, this condition doesn't hold.
--------

My opinion is,

--------
Two istream iterators are equal if :

both are end-of-stream iterators and this can no longer be read, or
both can read and use the same stream

from "The C++ Standard Library" by Josuttis.
--------

So I think whether a and b are equal has nothing to do
with *a and *b. Another question, "input iterators" is
different from "istream iterators"? I think they are the same.

Am I correct? Who can give me an explanation?
Better with an example. :-)


Thanks in advance,
George

George2
February 6th, 2003, 08:30 PM
Anyone knows the answer?

George

mwilliamson
February 6th, 2003, 08:36 PM
Basically it is saying if the indexes (the iterators) in the array (the vector) is equal, then the values should be equal. However, say you open two different istreams, one in binary and one in text. Then the value at the same position will not be the same.

George2
February 7th, 2003, 08:07 AM
Hi, mwilliamson buddies!

I can give you an sample that for two input iterators,
when i == j but *i != *j.

Here is the sample:

--------
#include <iterator>
#include <fstream>
#include <iostream>

using namespace std;

void main()
{
// c:\\file1.txt: 0 1 2 3
ifstream ifile ("c:\\file1.txt");

istream_iterator<int> r (ifile);
istream_iterator<int> s (ifile);

(r==s) ? cout << "equal" : cout << "not equal";
cout << endl;

++r;
++s;

cout << *r << endl;
cout << *s << endl;

(r==s) ? cout << "equal" : cout << "not equal";
cout << endl;
}
--------

Here are the outputs,

--------
equal
2
3
equal
--------


What is your opinion, mwilliamson?


Thanks in advance,
George

mwilliamson
February 7th, 2003, 09:26 AM
Interesting, I didn't know that istream did that. It seems when you increment the iterator, it also increments the file position. The iterators at still equal because of the number of times they have been incremented. I guess thats what they were trying to tell you :) When you

George2
February 7th, 2003, 09:57 AM
Hi, mwilliamson buddies!

I think input iterator i equals input iterator j means
they are pointing to the same input stream.

And *i equals *j means the dereference value of input iterator i at current position and the dereference value of input iterator j at current position are the same. I and j may be not pointing to the same input stream. So, i may be not equals j. As I pointed out before, am I correct?

What is your opinion?


Thanks in advance,
George

Philip Nicoletti
February 7th, 2003, 10:25 AM
I don't know if this will help or not ...

1) There are 5 CATEGORIES of iterators, one of
which is an input iterator. An input iterator
is anything that "acts like one", that is - has
the properties that are stated in the standard.

2) The standard supplies istream_iterator - an
iterator ADAPTER. It has the properties of an
input iterator along with others (the statements
that start "istream_iterator<...>"). I don't
think that inheritance is the correct concept
between istream_iterator and general input iterators,
but I could be wrong about that.

3) Look at the following code. Note: I changed the
contents of the input file as shown in the comments.
As the Josuttis book said, the iterators are equal
if they point to the same stream (and not end-of-stream),
or are both end of stream.


#include <iterator>
#include <fstream>
#include <iostream>

using namespace std;

int main()
{
// c:\\file1.txt: 0 1 2 3 4 5 6 7 8 9

ifstream ifile ("c:\\file1.txt");

istream_iterator<int> r (ifile);
istream_iterator<int> s (ifile);
istream_iterator<int> t;

cout << *r << endl;
cout << *r << endl;
cout << *r << endl;
cout << *s << endl;

(r==s) ? cout << "equal" : cout << "not equal";
cout << endl;

++r;
++s;
++r;
++s;
++s;
++s;
++s;
++s;

cout << *r << endl;
cout << *s << endl;
cout << *s << endl;

(r==s) ? cout << "r equals s" : cout << "r not equal to s" ;
cout << endl;
(t==s) ? cout << "t equals s" : cout << "t not equal to s" ;
cout << endl;

cout << endl << "now reading past-end-of-stream" << endl << endl;
++s;
(r==s) ? cout << "r equals s" : cout << "r not equal to s" ;
cout << endl;
(t==s) ? cout << "t equals s" : cout << "t not equal to s" ;
cout << endl;

return 0;
}



4) I think one reason that you are not getting definitive
answers is that normally, a programmer doesn't do
the "++=s" etc himself. The reason for istream_iterator's
existence is to allow streams to be used in algorithms.
Personnaly, that is the only way that I do use them. That
is not to say there are not circumstances when you would
want to - but I just don't think they are that common.

George2
February 7th, 2003, 09:50 PM
Thanks, Philip buddies!

George

Originally posted by Philip Nicoletti
I don't know if this will help or not ...

1) There are 5 CATEGORIES of iterators, one of
which is an input iterator. An input iterator
is anything that "acts like one", that is - has
the properties that are stated in the standard.

2) The standard supplies istream_iterator - an
iterator ADAPTER. It has the properties of an
input iterator along with others (the statements
that start "istream_iterator<...>"). I don't
think that inheritance is the correct concept
between istream_iterator and general input iterators,
but I could be wrong about that.

3) Look at the following code. Note: I changed the
contents of the input file as shown in the comments.
As the Josuttis book said, the iterators are equal
if they point to the same stream (and not end-of-stream),
or are both end of stream.


#include <iterator>
#include <fstream>
#include <iostream>

using namespace std;

int main()
{
// c:\\file1.txt: 0 1 2 3 4 5 6 7 8 9

ifstream ifile ("c:\\file1.txt");

istream_iterator<int> r (ifile);
istream_iterator<int> s (ifile);
istream_iterator<int> t;

cout << *r << endl;
cout << *r << endl;
cout << *r << endl;
cout << *s << endl;

(r==s) ? cout << "equal" : cout << "not equal";
cout << endl;

++r;
++s;
++r;
++s;
++s;
++s;
++s;
++s;

cout << *r << endl;
cout << *s << endl;
cout << *s << endl;

(r==s) ? cout << "r equals s" : cout << "r not equal to s" ;
cout << endl;
(t==s) ? cout << "t equals s" : cout << "t not equal to s" ;
cout << endl;

cout << endl << "now reading past-end-of-stream" << endl << endl;
++s;
(r==s) ? cout << "r equals s" : cout << "r not equal to s" ;
cout << endl;
(t==s) ? cout << "t equals s" : cout << "t not equal to s" ;
cout << endl;

return 0;
}



4) I think one reason that you are not getting definitive
answers is that normally, a programmer doesn't do
the "++=s" etc himself. The reason for istream_iterator's
existence is to allow streams to be used in algorithms.
Personnaly, that is the only way that I do use them. That
is not to say there are not circumstances when you would
want to - but I just don't think they are that common.