English 中文(简体)
String initialization with pair of iterators
原标题:

I m trying to initialize string with iterators and something like this works:

ifstream fin("tmp.txt");  
istream_iterator<char> in_i(fin), eos; 
//here eos is 1 over the end  
string s(in_i, eos);

but this doesn t:

ifstream fin("tmp.txt");
istream_iterator<char> in_i(fin), eos(fin);
/* here eos is at this same position as in_i*/
//moving eos forward 
for (int i = 0; i < 20; ++i)
{
    ++eos; 
}
// trying to initialize string with 
// pair of iterators gives me "" 
// result  
string s(in_i, eos);

Thank you.

最佳回答

I don t think you can advance the end iterator to a suitable position: to advance the iterator means to read input, also both iterators are referencing the same stream - therefore advancing one iterator means to advance the second. They both end up referencing the same position in the stream.

Unless you are willing to write or find an iterator adaptor (boost?) that does an operation on n items referenced by some iterator, it might not be possible to initialize the string like that. Or you read the value with other methods and set the value of the string later.

问题回答

istream_iterator is input so your second code fragment isn t correct, you can t do this (second pass). Please look here and pay attention to "single pass" algorithms support (second paragraph under "description" title). First fragment doesn t try to perform 2 passes.

Is this explanation OK? BTW SGI STL reference (from where I posted link) is somewhat outdated but very usable for some quick references (by my opinion). I d recommend it to be bookmarked.

The istream_iterator is a very limited iterator knows as a input iterator.

See: http://www.sgi.com/tech/stl/InputIterator.html

But basically for input iterators very few gurantees are made.
Specifically to your case:

i == j does not imply ++i == ++j.

So your first example is an iterator that is passed the end of stream. It is valid (as long as it is not incremented) and comparable to other iterators so works for reading the whole stream.

From the standard [24.5.1]/1:

[...] The constructor with no arguments istream_iterator() always constructs an end of stream input iterator object, which is the only legitimate iterator to be used for the end condition. [...] The main peculiarity of the istream iterators is the fact that ++ operators are not equality preserving, that is, i == j does not guarantee at all that ++i == ++j. Every time ++ is used a new value is read.

[24.5.1]/3

Two end-of-stream iterators are always equal. An end-of-stream iterator is not equal to a non-end-of-stream iterator. Two non-end-of-stream iterators are equal when they are constructed from the same stream

The first paragraph states that you cannot use any but end-of-stream iterators as end conditions, so your first usage is correct and expected. The third paragraph in the chapter states that any two non-end-of-stream iterators into the same stream are guaranteed to be equal at all times. That is, the second usage is correct from the language standpoint and will provide the results you are getting.

The last part of paragraph 1, where it states that i == j does not imply ++i == ++j deals with the particular case of one last element present in the stream. After incrementing the first of the iterators (either i or j) the datum is consumed by that iterator. Advancing the other iterator will hit the end of stream and thus the two iterators will differ. In all other cases (there is more than one datum left in the stream), ++i == ++j.

Also note that the sentence ++i == ++j executes two mutating operations on the same element (stream) and thus it is not which of the two iterators get the first/second datum in the stream.





相关问题
Simple JAVA: Password Verifier problem

I have a simple problem that says: A password for xyz corporation is supposed to be 6 characters long and made up of a combination of letters and digits. Write a program fragment to read in a string ...

Case insensitive comparison of strings in shell script

The == operator is used to compare two strings in shell script. However, I want to compare two strings ignoring case, how can it be done? Is there any standard command for this?

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

String initialization with pair of iterators

I m trying to initialize string with iterators and something like this works: ifstream fin("tmp.txt"); istream_iterator<char> in_i(fin), eos; //here eos is 1 over the end string s(in_i, ...

break a string in parts

I have a string "pc1|pc2|pc3|" I want to get each word on different line like: pc1 pc2 pc3 I need to do this in C#... any suggestions??

Quick padding of a string in Delphi

I was trying to speed up a certain routine in an application, and my profiler, AQTime, identified one method in particular as a bottleneck. The method has been with us for years, and is part of a "...

热门标签