Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

input, output iterators help needed SOS

Status
Not open for further replies.

lgang

Programmer
Oct 1, 2002
7
0
0
US
Hi buddies,

I don't know how to understand the input and output iterators are based on _single pass_ algo.

Here is the code:

ifstream ifile("0123.txt"); //file content is 0 1 2 3
istream_iterator<int, ptrdiff_t> r(ifile);
istream_iterator<int, ptrdiff_t> r(ifile);

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

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


How can I get the output as
2
3
equal

? Can any guru explain it to me?
How are they implemented under the hood?

Thanks a million!



 
Split it up into 2 lines

char* ptr = (r == s ? &quot;equal&quot;:&quot;not equal&quot;);
cout<<ptr<<endl;

Matt
 
Forgive me, the 2nd line should be read as
istream_iterator<int, ptrdiff_t> s(ifile); //r should be s.

You did not get my point. What I am asking is how r and s are operated. If the ptr r incremented, why s is also incremented?
++r;
++s;
//why now r points to 2? I assumed it should be 0.

Thanks.


 
Is the actual file content &quot;0 1 2 3&quot; as you state above?

If that is the case, you istream_iterator should be char and not int.

sizeof(int) = 4
sizeof(short) = 2
sizeof(char) = 1

in your case, I THINK that you are reading in &quot;1 2 &quot;

one space two space (4 bytes)

Check this and repost if it is not the solution.

Matt
 
No, it's good as int. The istream_iterator takes care of the formatting for you, just like an istream (e.g. cin) does.

The &quot;problem&quot; is that you made both iterators off the same ifstream, so they're both moving through the same file. You want to make two different ifstreams, then make an iterator for each of those.

As an aside, your istream_iterator appears to be slightly nonstandard; the second template parameter should be the type of character of the underlying file, and the ptrdiff_t would be the fourth parameter (optional, like the third). You might want to check on that.
 
Thanks a million. First it gives the result as I suggested. You can try it yourself if you don't believe it.

I am not complaining the code does not work, I am just curious how the code generates this funny results. Acutally somebody asked me this question and I can not figure it out why.

How r changed has an effect on s. What is going inside it? Just curious. In fact, I seldom use streams as I found it is slower than their counterpart in C.

Thanks
 
The iterators are typically implemented as containing a pointer to the stream with which they were constructed. The stream represents the open file.

A simple, probably incorrect, off-the-top-of-my-head definition might look like this:

Code:
  template< typename T >
class istream_iterator
{
  public:
    T operator*()
    {
        T val;
        (*stream) >> val;
        return val;
    }

  private:
    istream* stream;
};

Remember, that's overly simplistic and probably a little wrong, but it should give you the basic idea of how it works.

If you understand it in English better than in code, they're using the same stream because they were created from the same stream. When you dereference the iterators, they each read a value from the same stream. Whether you read from r, from s, or just from ifile, you're still getting values from the same place.

It's the same thing with regular pointers. Consider the following code:

Code:
int i = 0;
int* r;
int* s;

i++;
(*r)++;
(*s)++;

At this point, i == 3. You incremented it twice; two of those times were just through pointers.

With your iterators, they read from the same stream twice, since they just use the stream they point to.
 
think of streams as thread off a spool... The iterators don't actually move, when they advance, they are pulling more thread off. Infact I can only think of one way to look at two places in the same stream at a time, and that is using peek()... often times it is better to just suck it up and create a second stream to the same file.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top