 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Joshua Lehrer Guest
|
Posted: Sat Aug 19, 2006 6:31 pm Post subject: reading words from cin |
|
|
which is the proper loop to read words from cin:
using namespace std;
while (!cin.eof()) {
std::string s;
cin >> s;
cout << "word:" << s << endl;
}
or
while (1) {
std::string s;
cin >> s;
if (cin.eof()) break;
cout << "word:" << s << endl;
}
| Quote: | From my reading of the standard, it is unclear to me if reading the
last word and its end of file both populates the string and sets |
(cin.eof()==true), or if eof only gets set when trying to read and
there are no words left ,just the EOF marker.
from 21.3.7.9:
Begins by constructing a sentry object k as if k were constructed by
typename basic_istream<charT,traits>::sentry k(is). If bool(k) is true,
it calls str.erase() and then extracts characters from is and appends
them to str as if by calling str.append(1,c). If is.width() is greater
than zero, the maximum number n of characters appended is is.width();
otherwise n is str.max_size(). Characters are extracted and appended
until any of the following occurs:
- n characters are stored;
- endoffile occurs on the input sequence;
- isspace(c,getloc()) is true for the next available input character
c.
from 27.4.2.1.3, table 85 says that the eof bit indicates that an input
operation reached the end of an input sequence.
So, if the input operation (cin>>string) reads: "hello<eof>", does that
input operation "reach the end of an input sequence" and thus set
eof(), which would make the first loop correct? Or, does it read
"hello", with the subsequent read operation failing and setting EOF,
which would make the second loop correct?
Thanks,
joshua lehrer
http://www.lehrerfamily.com/
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Alf P. Steinbach Guest
|
Posted: Sun Aug 20, 2006 5:29 am Post subject: Re: reading words from cin |
|
|
* Joshua Lehrer:
| Quote: | which is the proper loop to read words from cin:
using namespace std;
while (!cin.eof()) {
std::string s;
cin >> s;
cout << "word:" << s << endl;
}
|
This loop fails to handle
1. That 'cin >> s' can fail due to other reasons than eof.
2. That 'cin >> s' can fail due to reaching eof before encountering any
non-whitespace character.
| Quote: | or
while (1) {
std::string s;
cin >> s;
if (cin.eof()) break;
cout << "word:" << s << endl;
}
|
This loop fails to handle
1. That 'cin >> s' can fail due to other reasons than eof.
| Quote: | From my reading of the standard, it is unclear to me if reading the
last word and its end of file both populates the string and sets
(cin.eof()==true), or if eof only gets set when trying to read and
there are no words left ,just the EOF marker.
|
The eof bit is set when trying to read beyond the end of the file (or
stream). End of file is detected by the read attempt. Thus, end of
file is not magically set when reading the last byte in a file, but when
trying to read a non-existent subsequent byte -- which is necessary to
determine whether a word includes further characters -- so if the last
byte of a file is part of the representation of the last character in
a word, then yes, reading that word must necessarily set the eof bit.
Here's what I'd consider a better loop, off the cuff (not tested! ):
for( ;; )
{
std::string s;
if( !(std::cin >> s) )
{
break;
}
std::cout << "word: " << s << std::endl;
}
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Angelo Zhou Guest
|
Posted: Sun Aug 20, 2006 5:36 am Post subject: Re: reading words from cin |
|
|
Joshua Lehrer wrote:
| Quote: | which is the proper loop to read words from cin:
using namespace std;
while (!cin.eof()) {
std::string s;
cin >> s;
cout << "word:" << s << endl;
}
or
while (1) {
std::string s;
cin >> s;
if (cin.eof()) break;
cout << "word:" << s << endl;
}
From my reading of the standard, it is unclear to me if reading the
last word and its end of file both populates the string and sets
(cin.eof()==true), or if eof only gets set when trying to read and
there are no words left ,just the EOF marker.
from 21.3.7.9:
Begins by constructing a sentry object k as if k were constructed by
typename basic_istream<charT,traits>::sentry k(is). If bool(k) is true,
it calls str.erase() and then extracts characters from is and appends
them to str as if by calling str.append(1,c). If is.width() is greater
than zero, the maximum number n of characters appended is is.width();
otherwise n is str.max_size(). Characters are extracted and appended
until any of the following occurs:
- n characters are stored;
- endoffile occurs on the input sequence;
- isspace(c,getloc()) is true for the next available input character
c.
from 27.4.2.1.3, table 85 says that the eof bit indicates that an input
operation reached the end of an input sequence.
So, if the input operation (cin>>string) reads: "hello<eof>", does that
input operation "reach the end of an input sequence" and thus set
eof(), which would make the first loop correct? Or, does it read
"hello", with the subsequent read operation failing and setting EOF,
which would make the second loop correct?
Thanks,
joshua lehrer
http://www.lehrerfamily.com/
|
std::string s;
while(std::cin >> s) {
std::cout << "word:" << s << std::endl;
}
That's enough to do the job.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Mon Aug 21, 2006 4:33 pm Post subject: Re: reading words from cin |
|
|
Joshua Lehrer wrote:
| Quote: | which is the proper loop to read words from cin:
using namespace std;
while (!cin.eof()) {
std::string s;
cin >> s;
cout << "word:" << s << endl;
}
or
while (1) {
std::string s;
cin >> s;
if (cin.eof()) break;
cout << "word:" << s << endl;
}
|
Neither. The idiomatic form is:
std::string s ;
while ( std::cin >> s ) {
std::cout << "word:" << s << std::endl ;
}
In general, the function ios::eof() is of almost no use before a
read has failed (indicated by ios::fail(), which is what the
implicit conversion to bool or the operator! use). Once
ios::fail() returns true, you can test:
ios::bad(): Something really went wrong. (Supposing the
implementation actually handles what went
wrong---many don't.)
ios::eof(): End of file has been seen. In many cases, this
indicates that there was not a format error, but
there are exceptions.
If neither of the above is true, there was an error in the
format of the input data (impossible for >> into a string).
| Quote: | From my reading of the standard, it is unclear to me if
reading the last word and its end of file both populates the
string and sets (cin.eof()==true), or if eof only gets set
when trying to read and there are no words left ,just the EOF
marker.
|
eofbit gets set whenever the streambuf returns EOF. Regardless
of the reason the istream was reading from the streambuf; it can
be set by reading look-ahead, if look-ahead was needed, but if,
for example, the string is followed by white space (e.g. a
newline), it won't be set.
| Quote: | from 21.3.7.9:
Begins by constructing a sentry object k as if k were constructed by
typename basic_istream<charT,traits>::sentry k(is). If bool(k) is true,
it calls str.erase() and then extracts characters from is and appends
them to str as if by calling str.append(1,c). If is.width() is greater
than zero, the maximum number n of characters appended is is.width();
otherwise n is str.max_size(). Characters are extracted and appended
until any of the following occurs:
- n characters are stored;
- endoffile occurs on the input sequence;
- isspace(c,getloc()) is true for the next available input character
c.
from 27.4.2.1.3, table 85 says that the eof bit indicates that
an input operation reached the end of an input sequence.
So, if the input operation (cin>>string) reads: "hello<eof>",
does that input operation "reach the end of an input sequence"
and thus set eof(), which would make the first loop correct?
|
It means that the first loop will work for this particular
input. That doesn't make it correct.
| Quote: | Or, does it read "hello", with the subsequent read operation
failing and setting EOF, which would make the second loop
correct?
|
The second loop will work with "hello\n<eof>". Neither loop
works in both cases.
For inputting more complicated data, such as numeric data, you
also have to consider format errors.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|