------ foo.cpp : BEGIN ------
#include <cassert>
#include <vector>
#include <string>
#include <iostream>
#include <iterator>
#include <fstream>
using namespace std;
int main ()
{
ifstream f("foo.in", ios_base::binary);
assert (f);
istream_iterator<string> b(f), e;
cout << "(1) File : ";
copy (b, e, ostream_iterator<string> (cout, " "));
cout << endl;
cout << "(2) File : ";
copy (b, e, ostream_iterator<string> (cout, " "));
cout << endl;
return 0;
}
------ foo.cpp : END --------
------ Compilation & Run : BEGIN ------
$ g++ --version
g++ (GCC) 3.3.1 (cygming special)
[---omitted---]
$ g++ -mno-cygwin foo.cpp
$ a
(1) File : abc xyz ijk pqr
(2) File : abc
------ Compilation & Run : END --------
Why do two copy()'s produce different output?
--
Alex Vinokur http://mathforum.org/library/view/10978.html http://sourceforge.net/users/alexvn 9 3151
Alex Vinokur wrote: ------ foo.cpp : BEGIN ------ #include <cassert> #include <vector> #include <string> #include <iostream> #include <iterator> #include <fstream> using namespace std;
int main () { ifstream f("foo.in", ios_base::binary); assert (f); istream_iterator<string> b(f), e;
cout << "(1) File : "; copy (b, e, ostream_iterator<string> (cout, " ")); cout << endl;
cout << "(2) File : "; copy (b, e, ostream_iterator<string> (cout, " ")); cout << endl;
return 0; } ------ foo.cpp : END --------
------ Compilation & Run : BEGIN ------
$ g++ --version g++ (GCC) 3.3.1 (cygming special) [---omitted---]
$ g++ -mno-cygwin foo.cpp
$ a (1) File : abc xyz ijk pqr (2) File : abc
------ Compilation & Run : END --------
Why do two copy()'s produce different output?
Probably because you didn't rewind the stream. The 'istream_iterator'
holds a reference to the stream it's initialised with. Any attempt to
read past the end of the file produce undefined behaviour.
Victor
"Victor Bazarov" <v.********@comAcast.net> wrote in message news:rz*************@newsread1.dllstx09.us.to.veri o.net... Alex Vinokur wrote:
[snip] Why do two copy()'s produce different output?
Probably because you didn't rewind the stream. The 'istream_iterator' holds a reference to the stream it's initialised with. Any attempt to read past the end of the file produce undefined behaviour.
[snip]
Something like:
------ foo1.cpp : BEGIN ------
#include <cassert>
#include <string>
#include <iostream>
#include <iterator>
#include <fstream>
using namespace std;
int main ()
{
ifstream f("foo.in");
assert (f);
istream_iterator<string> b(f), e;
cout << distance (b, e) << endl;
f.seekg (0, ios::beg);
cout << distance (b, e) << endl;
return 0;
}
------ foo1.cpp : END --------
------ Run : BEGIN ------
$ a
4
1
------ Run : END --------
What happened to 'b' after first 'distance'?
Where should one put 'seekg' (rewind) to get the same result after second 'distance'?
--
Alex Vinokur http://mathforum.org/library/view/10978.html http://sourceforge.net/users/alexvn
Alex Vinokur wrote: "Victor Bazarov" <v.********@comAcast.net> wrote in message news:rz*************@newsread1.dllstx09.us.to.veri o.net...
Alex Vinokur wrote: [snip]
Why do two copy()'s produce different output?
Probably because you didn't rewind the stream. The 'istream_iterator' holds a reference to the stream it's initialised with. Any attempt to read past the end of the file produce undefined behaviour.
[snip]
Something like:
------ foo1.cpp : BEGIN ------ #include <cassert> #include <string> #include <iostream> #include <iterator> #include <fstream> using namespace std;
int main () { ifstream f("foo.in"); assert (f); istream_iterator<string> b(f), e;
cout << distance (b, e) << endl; f.seekg (0, ios::beg); cout << distance (b, e) << endl;
return 0; } ------ foo1.cpp : END --------
------ Run : BEGIN ------
$ a 4 1
------ Run : END --------
What happened to 'b' after first 'distance'?
'distance' uses operator++ to count the number of increments. That
changes the original iterator, doesn't it?
Where should one put 'seekg' (rewind) to get the same result after second 'distance'?
Nowhere. Don't use 'distance'. Perhaps it's a bug in your library
implementation. Did you check how 'distance' worked? The trouble
with 'istream_iterator' is that the connection between it and the
stream is mutating even after you make a copy of the iterator. You
might get lucky that your stream can be brought back to the same
state somehow, or you might never get lucky, and the stream, once it
has been read, can never go back to its beginning...
Why do you need to do that, anyway?
Victor
"Victor Bazarov" <v.********@comAcast.net> wrote in message news:ux*************@newsread1.dllstx09.us.to.veri o.net... Alex Vinokur wrote: "Victor Bazarov" <v.********@comAcast.net> wrote in message news:rz*************@newsread1.dllstx09.us.to.veri o.net...
Alex Vinokur wrote: [snip]
Why do two copy()'s produce different output?
Probably because you didn't rewind the stream. The 'istream_iterator' holds a reference to the stream it's initialised with. Any attempt to read past the end of the file produce undefined behaviour.
[snip]
Something like:
------ foo1.cpp : BEGIN ------ #include <cassert> #include <string> #include <iostream> #include <iterator> #include <fstream> using namespace std;
int main () { ifstream f("foo.in"); assert (f); istream_iterator<string> b(f), e;
cout << distance (b, e) << endl; f.seekg (0, ios::beg); cout << distance (b, e) << endl;
return 0; } ------ foo1.cpp : END --------
------ Run : BEGIN ------
$ a 4 1
------ Run : END --------
What happened to 'b' after first 'distance'?
'distance' uses operator++ to count the number of increments. That changes the original iterator, doesn't it?
Where should one put 'seekg' (rewind) to get the same result after second 'distance'?
Nowhere. Don't use 'distance'. Perhaps it's a bug in your library implementation.
Microsoft C++ Version 13.00.9466 for 80x86,
Borland C++ 5.5.1,
Digital Mars C++ 8.38n
produce the same behavior.
Did you check how 'distance' worked? The trouble with 'istream_iterator' is that the connection between it and the stream is mutating even after you make a copy of the iterator. You might get lucky that your stream can be brought back to the same state somehow, or you might never get lucky, and the stream, once it has been read, can never go back to its beginning...
Why do you need to do that, anyway?
[snip]
I didn't need that, but I came across strange (to me) behavior of copy() while preparing my reply to thread http://groups-beta.google.com/group/...d64bb7a94fa3a/
Now I would like to understand this situation.
--
Alex Vinokur http://mathforum.org/library/view/10978.html http://sourceforge.net/users/alexvn
Alex Vinokur wrote: "Victor Bazarov" <v.********@comAcast.net> wrote in message news:ux*************@newsread1.dllstx09.us.to.veri o.net...
Alex Vinokur wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message news:rz*************@newsread1.dllstx09.us.to.veri o.net...
Alex Vinokur wrote:
[snip]
>Why do two copy()'s produce different output?
Probably because you didn't rewind the stream. The 'istream_iterator' holds a reference to the stream it's initialised with. Any attempt to read past the end of the file produce undefined behaviour.
[snip]
Something like:
------ foo1.cpp : BEGIN ------ #include <cassert> #include <string> #include <iostream> #include <iterator> #include <fstream> using namespace std;
int main () { ifstream f("foo.in"); assert (f); istream_iterator<string> b(f), e;
cout << distance (b, e) << endl; f.seekg (0, ios::beg); cout << distance (b, e) << endl;
return 0; } ------ foo1.cpp : END --------
------ Run : BEGIN ------
$ a 4 1
------ Run : END --------
What happened to 'b' after first 'distance'?
'distance' uses operator++ to count the number of increments. That changes the original iterator, doesn't it?
Where should one put 'seekg' (rewind) to get the same result after second 'distance'?
Nowhere. Don't use 'distance'. Perhaps it's a bug in your library implementation.
Microsoft C++ Version 13.00.9466 for 80x86, Borland C++ 5.5.1, Digital Mars C++ 8.38n produce the same behavior.
Did you check how 'distance' worked? The trouble with 'istream_iterator' is that the connection between it and the stream is mutating even after you make a copy of the iterator. You might get lucky that your stream can be brought back to the same state somehow, or you might never get lucky, and the stream, once it has been read, can never go back to its beginning...
Why do you need to do that, anyway?
[snip]
I didn't need that, but I came across strange (to me) behavior of copy() while preparing my reply to thread http://groups-beta.google.com/group/...d64bb7a94fa3a/
Now I would like to understand this situation.
If you feel like it, dig in the source of the C++ library (or libraries)
you're using. It seems that since 'copy' is a template, it probably gets
its arguments in the form of references (and not objects copied due to
passing by value). If it's so, the objects change while 'copy' does its
thing. How they change you can also discover by looking at the code. If
you find it interesting/revealing/puzzling, do post again.
You could also experiment with passing by value:
...
void foo(istream_iterator b, istream_iterator e)
{
std::copy(b, e, ...
}
int main()
{
...
foo(b, e);
// reset the stream
std::copy(b, e, ...
}
and see if it makes any difference...
V
On Wed, 21 Jul 2004 19:58:32 +0300, "Alex Vinokur"
<al****@big-foot.com> wrote: int main () { ifstream f("foo.in", ios_base::binary); assert (f); istream_iterator<string> b(f), e;
cout << "(1) File : "; copy (b, e, ostream_iterator<string> (cout, " ")); cout << endl;
cout << "(2) File : "; copy (b, e, ostream_iterator<string> (cout, " ")); cout << endl;
return 0; } (1) File : abc xyz ijk pqr (2) File : abc Why do two copy()'s produce different output?
When you take a copy of an input iterator, the original one is still
affected by changes to the copy. istream_iterator can only be used for
1-pass algorithms. Rewinding the stream and then constructing a new
iterator from the stream is the only safe way to do a second pass.
e.g. something like:
int main ()
{
ifstream f("foo.in", ios_base::binary);
assert (f);
istream_iterator<string> b(f), e;
cout << "(1) File : ";
copy (b, e, ostream_iterator<string> (cout, " "));
cout << endl;
f.seekg(0, std::ios_base::beg);
b = istream_iterator<string>(f);
cout << "(2) File : ";
copy (b, e, ostream_iterator<string> (cout, " "));
cout << endl;
return 0;
}
Tom
"tom_usenet" <to********@hotmail.com> wrote in message news:iv********************************@4ax.com... On Wed, 21 Jul 2004 19:58:32 +0300, "Alex Vinokur" <al****@big-foot.com> wrote:int main () { ifstream f("foo.in", ios_base::binary); assert (f); istream_iterator<string> b(f), e;
cout << "(1) File : "; copy (b, e, ostream_iterator<string> (cout, " ")); cout << endl;
cout << "(2) File : "; copy (b, e, ostream_iterator<string> (cout, " ")); cout << endl;
return 0; } (1) File : abc xyz ijk pqr (2) File : abc Why do two copy()'s produce different output? When you take a copy of an input iterator, the original one is still affected by changes to the copy. istream_iterator can only be used for 1-pass algorithms. Rewinding the stream and then constructing a new iterator from the stream is the only safe way to do a second pass. e.g. something like:
int main () { ifstream f("foo.in", ios_base::binary); assert (f); istream_iterator<string> b(f), e;
cout << "(1) File : "; copy (b, e, ostream_iterator<string> (cout, " ")); cout << endl;
f.seekg(0, std::ios_base::beg); b = istream_iterator<string>(f);
It doesn't help. cout << "(2) File : "; copy (b, e, ostream_iterator<string> (cout, " ")); cout << endl;
return 0; }
Tom
Here is some program which demonstrates behavior of istream_iterator.
====== File foo.cpp : BEGIN ======
#include <cassert>
#include <string>
#include <iostream>
#include <iterator>
#include <fstream>
using namespace std;
int main ()
{
ifstream f("foo.in", ios::binary);
assert (f);
cout << "Before istream_iterator : tellg() = " << f.tellg() << endl;
cout << endl;
istream_iterator<string> b(f), e;
cout << "--- First ---" << endl;
cout << "After istream_iterator : tellg() = " << f.tellg() << endl;
cout << "Output-1.1 = ";
copy (b, e, ostream_iterator<string> (cout, " "));
cout << endl;
cout << "After first copy : tellg() = " << f.tellg() << endl;
cout << "Output-1.2 = ";
copy (b, e, ostream_iterator<string> (cout, " "));
cout << endl;
cout << endl;
cout << "--- Second ---" << endl;
f.clear();
f.seekg(0, ios::beg);
cout << "After clear and seekg : tellg() = " << f.tellg() << endl;
cout << "Output-2.1 = ";
copy (b, e, ostream_iterator<string> (cout, " "));
cout << endl;
cout << "After second copy : tellg() = " << f.tellg() << endl;
cout << endl;
cout << "--- Third ---" << endl;
f.clear();
f.seekg(0, ios::beg);
cout << "After clear and seekg : tellg() = " << f.tellg() << endl;
b++;
cout << "After b++ : tellg() = " << f.tellg() << endl;
cout << "Output-3.1 = ";
copy (b, e, ostream_iterator<string> (cout, " "));
cout << endl;
cout << "After third copy : tellg() = " << f.tellg() << endl;
cout << endl;
return 0;
}
====== File foo.cpp : END ========
====== Compilation & Run : BEGIN ======
$ g++ --version
g++ (GCC) 3.3.1 (cygming special)
[---omitted---]
$ g++ foo.cpp
$ a
Before istream_iterator : tellg() = 0
--- First ---
After istream_iterator : tellg() = 3
Output-1.1 = aaa bbb ccc ddd
After first copy : tellg() = -1
Output-1.2 = aaa
--- Second ---
After clear and seekg : tellg() = 0
Output-2.1 = aaa aaa bbb ccc ddd
After second copy : tellg() = -1
--- Third ---
After clear and seekg : tellg() = 0
After b++ : tellg() = 3
Output-3.1 = aaa bbb ccc ddd
After third copy : tellg() = -1
====== Compilation & Run : END ========
--
Alex Vinokur http://mathforum.org/library/view/10978.html http://sourceforge.net/users/alexvn
Alex Vinokur wrote: "tom_usenet" <to********@hotmail.com> wrote in message news:iv********************************@4ax.com...
On Wed, 21 Jul 2004 19:58:32 +0300, "Alex Vinokur" <al****@big-foot.com> wrote:
int main () { ifstream f("foo.in", ios_base::binary); assert (f); istream_iterator<string> b(f), e;
cout << "(1) File : "; copy (b, e, ostream_iterator<string> (cout, " ")); cout << endl;
cout << "(2) File : "; copy (b, e, ostream_iterator<string> (cout, " ")); cout << endl;
return 0; } (1) File : abc xyz ijk pqr (2) File : abc Why do two copy()'s produce different output? When you take a copy of an input iterator, the original one is still affected by changes to the copy. istream_iterator can only be used for 1-pass algorithms. Rewinding the stream and then constructing a new iterator from the stream is the only safe way to do a second pass. e.g. something like:
int main () { ifstream f("foo.in", ios_base::binary); assert (f); istream_iterator<string> b(f), e;
cout << "(1) File : "; copy (b, e, ostream_iterator<string> (cout, " ")); cout << endl;
f.seekg(0, std::ios_base::beg); b = istream_iterator<string>(f);
It doesn't help.
You probably also need to do
f.clear();
before f.seekg( ..
Once the EOF is reached, the stream becomes non-responsive until
you clear its error state.
V
cout << "(2) File : "; copy (b, e, ostream_iterator<string> (cout, " ")); cout << endl;
return 0; }
Tom
[...]
"Victor Bazarov" <v.********@comAcast.net> wrote in message news:lG*************@newsread1.dllstx09.us.to.veri o.net...
[snip] If you feel like it, dig in the source of the C++ library (or libraries) you're using. It seems that since 'copy' is a template, it probably gets its arguments in the form of references (and not objects copied due to passing by value). If it's so, the objects change while 'copy' does its thing. How they change you can also discover by looking at the code. If you find it interesting/revealing/puzzling, do post again.
You could also experiment with passing by value:
... void foo(istream_iterator b, istream_iterator e) { std::copy(b, e, ... }
int main() { ... foo(b, e); // reset the stream std::copy(b, e, ... }
and see if it makes any difference...
V
We can see that there is no difference between passing by value and passing by reference because
a position of the pointer in istream 'f' (not istream_iterator 'b') determines such behavior.
====== foo.cpp : BEGIN ======
#include <cassert>
#include <string>
#include <iostream>
#include <iterator>
#include <fstream>
using namespace std;
void copy_by_value(istream_iterator<string> b, istream_iterator<string> e)
{
copy (b, e, ostream_iterator<string> (cout, " "));
}
void copy_by_ref(const istream_iterator<string>& b, const istream_iterator<string>& e)
{
copy (b, e, ostream_iterator<string> (cout, " "));
}
void test_by_value()
{
cout << "=== test_by_value ===" << endl;
ifstream f("foo.in", ios_base::binary);
assert (f);
cout << "Before istream_iterator : tellg() = " << f.tellg() << endl;
istream_iterator<string> b(f), e;
cout << "After istream_iterator : tellg() = " << f.tellg() << endl;
cout << "Output-1 =";
copy_by_value (b, e);
cout << endl;
cout << "After copy_by_value : tellg() = " << f.tellg() << endl;
cout << "Output-2 =";
copy (b, e, ostream_iterator<string> (cout, " "));
cout << endl;
cout << endl;
}
void test_by_ref()
{
cout << "=== test_by_ref ===" << endl;
ifstream f("foo.in", ios_base::binary);
assert (f);
cout << "Before istream_iterator : tellg() = " << f.tellg() << endl;
istream_iterator<string> b(f), e;
cout << "After istream_iterator : tellg() = " << f.tellg() << endl;
cout << "Output-1 =";
copy_by_ref (b, e);
cout << endl;
cout << "After copy_by_ref : tellg() = " << f.tellg() << endl;
cout << "Output-2 =";
copy (b, e, ostream_iterator<string> (cout, " "));
cout << endl;
cout << endl;
}
int main ()
{
test_by_value();
test_by_ref();
return 0;
}
====== foo.cpp : END ========
###### Run : BEGIN ######
=== test_by_value ===
Before istream_iterator : tellg() = 0
After istream_iterator : tellg() = 3
Output-1 =aaa bbb ccc ddd
After copy_by_value : tellg() = -1
Output-2 =aaa
=== test_by_ref ===
Before istream_iterator : tellg() = 0
After istream_iterator : tellg() = 3
Output-1 =aaa bbb ccc ddd
After copy_by_ref : tellg() = -1
Output-2 =aaa
###### Run : END ######
--
Alex Vinokur http://mathforum.org/library/view/10978.html http://sourceforge.net/users/alexvn This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Bill Rudolph |
last post by:
The member function basic_ios::operator!() returns the bool result of
the basic_ios::fail() function which is true if either failbit or
badbit is set (This is per p. 616 of TC++PL by B. Stroustrup...
|
by: Alex Vinokur |
last post by:
ofstream outfile ("out");
ifstream infile ("in");
istream_iterator<char> iter(infile), eos;
Is it possible to copy 'infile' to 'outfile' using 'iter' and 'eos'?
--
Alex Vinokur...
|
by: NPC |
last post by:
Hi,
Is there any way to use an istream_iterator<> in a way which inserts each
element at the end of a newline character rather than a space character?
Could be it looks for any type of whitespace...
|
by: alberto |
last post by:
I am learning STL with the book STL Tutorial and Reference guide (1 edition),
the following example don't run :
int main()
{
// Initialize array a with 10 integers:
int a = {12, 3, 25, 7, 11,...
|
by: Shuch |
last post by:
Hi all,
i m trying to read from a file and then copy it into an array...my
code is as follow..it runs fine but i cant understand y it doesnt show
me any output??
here is my code...
using...
|
by: jmoy.matecon |
last post by:
I get an error while compiling the following program:
int main()
{
vector<int> v(istream_iterator<int>(cin),
istream_iterator<int>());
copy(v.begin(),v.end(),ostream_iterator<int>(cout,"\n"));...
|
by: Juha Nieminen |
last post by:
I'm using gcc 3.3.5. This code:
std::set<std::stringt(std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>());
gives a strange error message:
error: cannot use...
|
by: arnuld |
last post by:
It works fine. any advice on making it better or if I can
improve my C++ coding skills:
/* C++ Primer - 4/e
*
* Chapter 9 - Sequential Containers
* exercise 9.18 - STATEMENT
* ...
|
by: ryjfgjl |
last post by:
ExcelToDatabase: batch import excel into database automatically...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, we are pleased to welcome back...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, we are pleased to welcome back...
|
by: Vimpel783 |
last post by:
Hello!
Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
|
by: ArrayDB |
last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
|
by: Defcon1945 |
last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
|
by: Shællîpôpï 09 |
last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
|
by: af34tf |
last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
|
by: Faith0G |
last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
| |