Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

while (cin >> x)

1,887 views
Skip to first unread message

Andrew Z

unread,
Jun 9, 2016, 12:08:20 AM6/9/16
to
Hello,
in the "Accelerated C++" book, that i'm reading, the below code is used as an example of using CIN to determine the number of the previously entered values.

[code]

while (cin >> x) {
++count;
sum += x ;
}

[/code]

From the reference i understood that cin/cout are created and kept "alive" for the duration of the program execution. If i were to have some high frequency input data on CIN for rather long period of time then, potentially, by checking number of values sent with the code above, i could run into memory or type length problems...

I'm sure my imagination is running wild, dueto the luck of knowledge. Appreciate your explanation.

Barry Schwarz

unread,
Jun 9, 2016, 1:54:58 AM6/9/16
to
On Wed, 8 Jun 2016 21:08:07 -0700 (PDT), Andrew Z <for...@gmail.com>
wrote:
The frequency of input does not matter. Two things that do matter are
the number of inputs and the actual values.

If sum is a signed integer, then it is possible to eventually exceed
the maximum value for that type. Underflowing the minimum value is
also possible.

The same is true if x is a floating point type.

If sum is a std::string, then you could possibly exceed the largest
allowable length or you could run out of memory before that happens.

Since you are accepting input from the user, these are not likely
events. His fingers will fall off sooner.

--
Remove del for email

Ralf Goertz

unread,
Jun 9, 2016, 3:25:50 AM6/9/16
to
Am Wed, 08 Jun 2016 22:54:45 -0700
schrieb Barry Schwarz <schw...@dqel.com>:

> On Wed, 8 Jun 2016 21:08:07 -0700 (PDT), Andrew Z <for...@gmail.com>
> wrote:
>
> >while (cin >> x) {
> > ++count;
> > sum += x ;
> >}

> If sum is a std::string, then you could possibly exceed the largest
> allowable length or you could run out of memory before that happens.
>
> Since you are accepting input from the user, these are not likely
> events. His fingers will fall off sooner.

Except when cin is redirected.


Juha Nieminen

unread,
Jun 9, 2016, 8:17:38 AM6/9/16
to
Andrew Z <for...@gmail.com> wrote:
> while (cin >> x) {

This just means that it will read space-delimited strings and (try to) convert them
to the type of x (eg. to int if that's the type of x). Since the return value of the
operator>> is a referece to cin itself, and cin has an implicit conversion to bool
operator which tells if the stream is still in a good state, the loop will end
when the input ends or there some kind of error with the reading.

It is not a very good way of reading any kind of input except in extremely
narrow situations (where you can control exactly what is fed to the program
as input), but it suffices as a simple beginner example.

> From the reference i understood that cin/cout are created and kept
> "alive" for the duration of the program execution. If i were to have
> some high frequency input data on CIN for rather long period of time
> then, potentially, by checking number of values sent with the code
> above, i could run into memory or type length problems...

You aren't going to run into memory problems unless you are storing
every single value you are getting from cin (eg. into a vector).
As for the counter value, if it's your typical int, it would probably
take days or months of feeding the program input before it wraps around,
at the speeds that text can be fed to a C++ stream. (If the counter
is 64-bit, the universe will cease to exist before it wraps around.)

But if that's a worry, it's trivial to add a conditional to check
if the counter is getting too large.

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---

Paavo Helde

unread,
Jun 9, 2016, 9:31:08 AM6/9/16
to
On 9.06.2016 15:17, Juha Nieminen wrote:
> Andrew Z <for...@gmail.com> wrote:
>> while (cin >> x) {
>
> This just means that it will read space-delimited strings and (try to) convert them
> to the type of x (eg. to int if that's the type of x). Since the return value of the
> operator>> is a referece to cin itself, and cin has an implicit conversion to bool
> operator which tells if the stream is still in a good state, the loop will end
> when the input ends or there some kind of error with the reading.
>
> It is not a very good way of reading any kind of input except in extremely
> narrow situations (where you can control exactly what is fed to the program
> as input), but it suffices as a simple beginner example.
>
>> From the reference i understood that cin/cout are created and kept
>> "alive" for the duration of the program execution. If i were to have
>> some high frequency input data on CIN for rather long period of time
>> then, potentially, by checking number of values sent with the code
>> above, i could run into memory or type length problems...
>
> You aren't going to run into memory problems unless you are storing
> every single value you are getting from cin (eg. into a vector).
> As for the counter value, if it's your typical int, it would probably
> take days or months of feeding the program input before it wraps around,
> at the speeds that text can be fed to a C++ stream. (If the counter
> is 64-bit, the universe will cease to exist before it wraps around.)

This is a bit exaggerated. With a modest 1000 words per second input
rate a 64-bit counter gets wrapped around already in 800 million years
(and a 32-bit counter in 50 days).

Cheers
Paavo


Fred.Zwarts

unread,
Jun 9, 2016, 9:38:01 AM6/9/16
to
"Barry Schwarz" schreef in bericht
news:2l0ilbh03fqgtv4kb...@4ax.com...
If x and sum are ints, even 64 bit integers, and the user is not restricted
to typing small values, sum may overflow very soon.

Andrew Z

unread,
Jun 9, 2016, 9:55:19 AM6/9/16
to
Juha,

> operator which tells if the stream is still in a good state, the loop will end
> when the input ends or there some kind of error with the reading.

that is another question i had - in the book this loop is _after_ all read/wrte to std was done. so in my mind, by the time "when" starts to execute, CIN has no data (empty stream since everything was already read) and the loop should be infinite. It seems that i do not understand how iostreams is implemented/designed. Where can i read on it in "beginners" words?

Gentlemen, thank you for input. It is making sense now.


Dan Cross

unread,
Jun 9, 2016, 11:43:28 AM6/9/16
to
In article <t7WdndCfj_4N8sTK...@giganews.com>,
Quite modest, indeed. On my 2010-era workstation and an old version of
GCC, this trivial program takes just under 15 minutes to overflow a 32-bit
unsigned integer:

: spitfire; uname -m -s
Linux x86_64
: spitfire; cat foo.cc
#include <iostream>

int
main()
{
unsigned int counter = 1;
unsigned long sum = 0;
int num;

std::cout << "sizeof(counter) = " << sizeof(counter) << std::endl;
std::cout << "sizeof(sum) = " << sizeof(sum) << std::endl;
while (std::cin >> num && ++counter != 0)
sum += num;
std::cout << "counter = " << counter << ", sum = " << sum << std::endl;

return 0;
}
: spitfire; make foo
g++ foo.cc -o foo
: spitfire; yes 1 | time ./foo
sizeof(counter) = 4
sizeof(sum) = 8
counter = 0, sum = 4294967294
851.73user 4.74system 14:16.74elapsed 99%CPU (0avgtext+0avgdata 1204maxresident)k
0inputs+0outputs (0major+750minor)pagefaults 0swaps
: spitfire;

- Dan C.

Öö Tiib

unread,
Jun 9, 2016, 12:03:59 PM6/9/16
to
Then it also takes some more than 100K years to overflow 64-bit unsigned
counter. For perspective of running software it is as far in the future as is the
end of the universe since any actual hardware capable of running it will decay
long before.

Dan Cross

unread,
Jun 9, 2016, 12:28:10 PM6/9/16
to
In article <cdad4610-978b-4290...@googlegroups.com>,
Believing that the hardware will fail before overflowing a 64-bit integer
by incrementing from zero is a fair assumption. However 32-bit counters
are still used quite frequently and can -- and regularly do -- overflow
rather quickly. Caveat programmer.

- Dan C.

Cholo Lennon

unread,
Jun 9, 2016, 12:32:43 PM6/9/16
to
On 06/09/2016 08:39 AM, Stefan Ram wrote:
> Andrew Z <for...@gmail.com> writes:
>>From the reference i understood that cin/cout are created and
>> kept "alive" for the duration of the program execution. If i
>> were to have some high frequency input data on CIN for rather
>> long period of time then, potentially, by checking number of
>> values sent with the code above, i could run into memory or
>> type length problems...
>
> I have no idea what »CIN« refers to.

C'mon... you know it (we all know it)!
Why this newsgroup is so hostile to newcomers/newbies?

>
> The code you showed is a teaching example simplified
> for beginners. It will not necessarily be written this
> way to count the votes for the president's election.
>
> It needs to be put into context, for example,
>
> struct S
> { S & operator ++() { return *this; }
> S operator ++( int ) { return *this; }
> S & operator +=( const S & o ){ return *this; }
> operator bool(){ return false; }};
> inline S & operator >>( S & object, S & object1 )
> { return object; }
>
> int main()
> { S cin, x, count, sum;
>
> while (cin >> x) {
> ++count;
> sum += x ;
> }
>
> }
>
> Thus, one should post complete programs.
>
>


--
Cholo Lennon
Bs.As.
ARG

Barry Schwarz

unread,
Jun 9, 2016, 1:21:10 PM6/9/16
to
On Thu, 9 Jun 2016 06:55:05 -0700 (PDT), Andrew Z <for...@gmail.com>
wrote:

>Juha,
>
>> operator which tells if the stream is still in a good state, the loop will end
>> when the input ends or there some kind of error with the reading.
>
>that is another question i had - in the book this loop is _after_ all read/wrte to std was done. so in my mind, by the time "when" starts to execute, CIN has no data (empty stream since everything was already read) and the loop should be infinite. It seems that i do not understand how iostreams is implemented/designed. Where can i read on it in "beginners" words?

C++ is case sensitive. It will eliminate confusion (and snide
remarks) if your text reflects this.

What do you mean when you say cin is empty?

If you mean it has reached end of file, then the while condition
will evaluate to false, the substatement will not execute, and control
will flow to the statement following the while statement.

If you mean the stream is waiting for more input, such as from the
keyboard, then the evaluation of the condition will wait for that
input. After this evaluation concludes, the substatement will execute
of not based on the evaluation result.

In neither case will the loop iterate an infinite number of times.

As a beginner, you should not care how streams are implemented or
designed. That is an advanced and system dependent topic. For now,
you should be content to use the standard functions and operators to
transfer data between the stream and your program.

Fred.Zwarts

unread,
Jun 10, 2016, 3:08:02 AM6/10/16
to
"Cholo Lennon" schreef in bericht news:njc5mt$6r6$1...@gioia.aioe.org...
>
>On 06/09/2016 08:39 AM, Stefan Ram wrote:
>> Andrew Z <for...@gmail.com> writes:
>>>From the reference i understood that cin/cout are created and
>>> kept "alive" for the duration of the program execution. If i
>>> were to have some high frequency input data on CIN for rather
>>> long period of time then, potentially, by checking number of
>>> values sent with the code above, i could run into memory or
>>> type length problems...
>>
>> I have no idea what »CIN« refers to.
>
>C'mon... you know it (we all know it)!
>Why this newsgroup is so hostile to newcomers/newbies?
>

Frustration probably, because the compiler we have to work with every day is
equally hostile. :)

Andrew Z

unread,
Jun 10, 2016, 4:27:09 PM6/10/16
to
On Thursday, June 9, 2016 at 1:21:10 PM UTC-4, Barry Schwarz wrote:
> On Thu, 9 Jun 2016 06:55:05 -0700 (PDT), Andrew Z <for...@gmail.com>
> wrote:
>
> >Juha,
> >
> >> operator which tells if the stream is still in a good state, the loop will end
> >> when the input ends or there some kind of error with the reading.
> >
> >that is another question i had - in the book this loop is _after_ all read/wrte to std was done. so in my mind, by the time "when" starts to execute, CIN has no data (empty stream since everything was already read) and the loop should be infinite. It seems that i do not understand how iostreams is implemented/designed. Where can i read on it in "beginners" words?
>
> C++ is case sensitive. It will eliminate confusion (and snide
> remarks) if your text reflects this.

Got it. Thank you for pointing out.

>
> What do you mean when you say cin is empty?

Barry,
thank you for help.
This is how i _imagine_ the cin works.
[code]
cout<< " Please enter your First name: ";
string name;
cin >> name ;
cout << "Hello, " << name << "!" << endl ;
[/code]
So at line 3 (cin >> name), the value read from cin is assigned to "name".
Now, lets say i want to ask for input twice:
[code]
cout<< " Please enter your First name: ";
string name;
cin >> name ;
cout << "Hello, " << name << "!" << endl ;
string Lname;
cout<< " Please enter your Last name: ";
cin >> Lname ;
cout << "Hello, " << name << "!" << endl ;
[/code]
The cin has value(s) for "name" first and then (after some time) values for "Lname".
(again -in my mind) After i read the input (into a variable) the cin gets cleared out, and the next input value can be read. This is obviously wrong, since a "while" condition, obtains values for everything that was entered previously.
Here is the complete original code:
[code]
int main() {
cout<< " Please enter your First name: ";
string name;
cin >> name ;
cout << "Hello, " << name << "!" << endl ;
cout << "Please enter your Midterm and Final exam grades: " ;
double midterm, final;
cin >> midterm >> final ;

// ask for homework grades
cout << " Please enter your Homework grades, "
" Followed by the end-of-flle: " ;

// the number and sum of the grades read so far
int count = 0;
double sum = 0;
// the variable into which to read
double x ;
/*
invariant:
we have read count grades for far, and sum is the sum of the first count grades
*/

while (cin >> x) {
++count;
sum += x ;
}
// rest of the code is removed.
return 0;
}
[/code]

Thank you.

Rosario19

unread,
Jun 11, 2016, 12:26:52 AM6/11/16
to
On Wed, 8 Jun 2016 21:08:07 -0700 (PDT), Andrew Z wrote:

>Hello,
> in the "Accelerated C++" book, that i'm reading, the below code is used as an example of using CIN to determine the number of the previously entered values.
>
>[code]
>
>while (cin >> x) {
> ++count;
> sum += x ;
>}
>
>[/code]

i find cin >> not good for get input...
possibly it is better use low functions from the C + malloc() free()
and write from there some functions for the input
even in C++

possibly in C and in C++ there are not hight level function for to get
input from stdin sufficietly robust or strong ( i not know the word
right)

Barry Schwarz

unread,
Jun 11, 2016, 6:44:59 AM6/11/16
to
On Fri, 10 Jun 2016 13:26:56 -0700 (PDT), Andrew Z <for...@gmail.com>
wrote:

>On Thursday, June 9, 2016 at 1:21:10 PM UTC-4, Barry Schwarz wrote:

<snip>

>> What do you mean when you say cin is empty?
>
>Barry,
> thank you for help.
> This is how i _imagine_ the cin works.

Your imagination is incorrect.

>[code]
>cout<< " Please enter your First name: ";
> string name;
> cin >> name ;
> cout << "Hello, " << name << "!" << endl ;
>[/code]
>So at line 3 (cin >> name), the value read from cin is assigned to "name".
>Now, lets say i want to ask for input twice:
>[code]
>cout<< " Please enter your First name: ";
> string name;
> cin >> name ;
> cout << "Hello, " << name << "!" << endl ;
> string Lname;
>cout<< " Please enter your Last name: ";
> cin >> Lname ;
> cout << "Hello, " << name << "!" << endl ;
>[/code]
>The cin has value(s) for "name" first and then (after some time) values for "Lname".
>(again -in my mind) After i read the input (into a variable) the cin gets cleared out, and the next input value can be read. This is obviously wrong, since a "while" condition, obtains values for everything that was entered previously.

That last sentence makes no sense. For visualization purposes,
imagine that there is a FIFO queue associated with cin. Something
like a paper towel dispenser where a supply of towels is added at the
top and towels are pulled off one by one at the bottom. cin's job is
to transfer data from the queue to a variable. If the variable is a
string, the data is transferred as is. If the variable is an int, the
data is first converted before being stored in the variable. Similarly
for other types of variables.

In most cases, when cin extracts characters from the queue, it will
ignore any white space until it finds a non-white space one. It then
extracts "meaningful" characters until it has a reason to stop. The
two normal reasons to stop are finding another white space character
or finding a character that is invalid for the variable type. Two
abnormal reasons for stopping are an error when data is being
transferred to the queue or a signal indicating there is no more data
(referred to commonly as end of file). Simply having an empty queue
is neither an error nor a terminating condition.. It simply means cin
must wait until more data arrives.

>Here is the complete original code:
>[code]
>int main() {
> cout<< " Please enter your First name: ";

At this point it would be perfectly legal for you to enter
" John 96 82 88 93 79 " and press Enter. As a result, the queue
would contain
" John 96 82 88 93 79 \n"

To see how the processing differs when you enter the data one at a
time, see iteration 4 below.

> string name;
> cin >> name ;

The white space is skipped, John is transferred to name, and the queue
no contains
" 96 82 88 93 79 \n"

> cout << "Hello, " << name << "!" << endl ;
> cout << "Please enter your Midterm and Final exam grades: " ;
> double midterm, final;
> cin >> midterm >> final ;

The white space is skipped, midterm is set to 96.0, white space is
skipped, final is set to 82.0, and the queue now contains
" 88 93 79 \n"

> // ask for homework grades
> cout << " Please enter your Homework grades, "
> " Followed by the end-of-flle: " ;
>
> // the number and sum of the grades read so far
> int count = 0;
> double sum = 0;
> // the variable into which to read
> double x ;
> /*
> invariant:
> we have read count grades for far, and sum is the sum of the first count grades
> */
>
> while (cin >> x) {

In iteration 1, white space is skipped, x is set to 88.0, the
condition evaluates to true, and the queue now contains
" 93 79 \n".

In iteration 2, white space is skipped, x is set to 93.0, the
condition evaluates to true, and the queue now contains
" 79 \n".

In iteration 3, white space is skipped, x is set to 79.0, the
condition evaluates to true, and the queue now contains
" \n".

In iteration 4, white space is skipped and the queue is empty. cin
waits for more typing. The condition is still being evaluated. You
type "91" and press Enter. The queue now contains
"91\n". x is set to 91.0, the condition evaluates to true, and the
queue now contains
"\n".

In iteration 5, the initial processing the same as iteration 4. Now
you signal EOF (^D on Unix, ^Z on Windows, etc) and press Enter. The
while condition evaluates to false and you exit the while loop.

> ++count;
> sum += x ;

These statements are process only during iterations 1-4, not 5.

>}
> // rest of the code is removed.
> return 0;
>}
>[/code]
>
>Thank you.

Andrew Z

unread,
Jun 11, 2016, 12:02:24 PM6/11/16
to
On Saturday, June 11, 2016 at 6:44:59 AM UTC-4, Barry Schwarz wrote:

> In iteration 5, the initial processing the same as iteration 4. Now
> you signal EOF (^D on Unix, ^Z on Windows, etc) and press Enter. The
> while condition evaluates to false and you exit the while loop.
>
> > ++count;
> > sum += x ;
>
> These statements are process only during iterations 1-4, not 5.
>

Barry , perfect and detailed explanation. Thank you very much for finding time and putting the effort in breaking this down for me.
Finally i got it.

Thank you
Andrew
0 new messages