From: albert.mills on
Hi ,

I am self studyign "Essential c++" which gives the following problem
and code. I don't get the code: the condition in the while statement
uses cin, but shouldsn't you input a variable using cin and then use
it with the while loop? Also how does cin>>while satisfy the problem?
i tried running the code as given, and with a value assigned to ival,
but it doesn't work.

Write a program to read in a sequence of integers from standard input.
Place the values, in
turn, in a built-in array and a vector. Iterate over the containers to
sum the values. Display
the sum and average of the entered values to standard output.

#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> ivec;
int ival;
while (cin >> ival)
ivec.push_back(ival);
// we could have calculated the sum as we entered the
// values, but the idea is to iterate over the vector ...
for (int sum = 0, ix = 0; ix < ivec.size(); ++ix)
sum += ivec[ix];
int average = sum / ivec.size();

cout << "Sum of " << ivec.size()
<< " elements: " << sum
<< ". Average: " << average << endl;
}
From: R. Scott Mellow on
albert.mills(a)googlemail.com wrote:
> Hi ,
>
> I am self studyign "Essential c++" which gives the following problem
> and code. I don't get the code: the condition in the while statement
> uses cin, but shouldsn't you input a variable using cin and then use
> it with the while loop? Also how does cin>>while satisfy the problem?
> i tried running the code as given, and with a value assigned to ival,
> but it doesn't work.
>
> Write a program to read in a sequence of integers from standard input.
> Place the values, in
> turn, in a built-in array and a vector. Iterate over the containers to
> sum the values. Display
> the sum and average of the entered values to standard output.

[snip]

> while (cin >> ival)
> ivec.push_back(ival);

This would be more readable formatted thusly:

while(cin >> ival)
{
ivec.push_back(ival);
}

std::cin is an object of type std::istream. std::istream objects are
convertible to a bool which is the type expected in the while condition.
Also, std::istream's >> operator returns a reference to the object it's
called with. Think of it acting like the following code:

int inputValue = 0;
std::istream refStream = std::cin.operator >>(inputValue);
bool itWorked = refStream;
if(itWorked)
{
whatever
}

More specifically, the istream object's fail state is used for the
conversion to bool. So, in English, the while loop's condition could be
stated like this:

While the std::cin object is not in a fail state after calling its
stream extraction operator.


hth
--
Randy



From: Daniel T. on
"albert.mills(a)googlemail.com" <albert.mills(a)googlemail.com> wrote:

> I am self studyign "Essential c++" which gives the following problem
> and code. I don't get the code: the condition in the while statement
> uses cin, but shouldsn't you input a variable using cin and then use
> it with the while loop?

No, that part is right. "cin >> ival" will return false if cin cannot
properly assign a new value to ival, which is the behavior you want.

> Also how does cin>>while satisfy the problem?

It allows you to collect the input in a clean way.

> Write a program to read in a sequence of integers from standard input.
> Place the values, in
> turn, in a built-in array and a vector. Iterate over the containers to
> sum the values. Display
> the sum and average of the entered values to standard output.
>
> #include <iostream>
> #include <vector>
> using namespace std;
> int main()
> {
> vector<int> ivec;
> int ival;
> while (cin >> ival)
> ivec.push_back(ival);
> // we could have calculated the sum as we entered the
> // values, but the idea is to iterate over the vector ...
> for (int sum = 0, ix = 0; ix < ivec.size(); ++ix)
> sum += ivec[ix];
> int average = sum / ivec.size();
>
> cout << "Sum of " << ivec.size()
> << " elements: " << sum
> << ". Average: " << average << endl;
> }

The code presented above should not compile. I'm assuming that it is an
old book? Look for an errata.

#include <iostream>
#include <vector>

using namespace std;

int main()
{
vector<int> ivec;
int ival;
while (cin >> ival)
ivec.push_back(ival);
// we could have calculated the sum as we entered the
// values, but the idea is to iterate over the vector ...
int sum = 0;
for (int ix = 0; ix < ivec.size(); ++ix)
sum += ivec[ix];
int average = sum / ivec.size();

cout << "Sum of " << ivec.size()
<< " elements: " << sum
<< ". Average: " << average << endl;
}

// sample run:

1 2 3 4 5 6 7 8 9 e
Sum of 9 elements: 45. Average: 5

A better version is:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>

using namespace std;

int main()
{
vector<int> vec;
copy(istream_iterator<int>(cin), istream_iterator<int>(),
back_inserter(vec));
const int sum = accumulate(vec.begin(), vec.end(), 0);
cout << "Sum of " << vec.size()
<< " elements: " << sum
<< ". Average: " << ( sum / vec.size() )
<< endl;
}
From: Triple-DES on
On 26 Jun, 01:44, "Daniel T." <danie...(a)earthlink.net> wrote:
[snip]
> A better version is:
>
> #include <algorithm>
> #include <iostream>
> #include <iterator>
> #include <numeric>
> #include <vector>
>
> using namespace std;
>
> int main()
> {
>    vector<int> vec;
>    copy(istream_iterator<int>(cin), istream_iterator<int>(),
>          back_inserter(vec));
>    const int sum = accumulate(vec.begin(), vec.end(), 0);
>    cout << "Sum of " << vec.size()
>       << " elements: " << sum
>       << ". Average: " << ( sum / vec.size() )
>       << endl;
> }

Except of course if no ints are entered in which case the behaviour is
undefined :)

DP
From: Francis Glassborow on
R. Scott Mellow wrote:
>
> std::cin is an object of type std::istream. std::istream objects are
> convertible to a bool

Well strictly speaking they are not (they were for a brief period of 4
months in the mid-90s when the Draft C++ Standard included a design
error which got incorporated into a single release of Borland C++). What
they are convertible to is some variety of void*, I forget exactly
which. That in turn can be used in a control expression such as is
required in a while()

which is the type expected in the while condition.
> Also, std::istream's >> operator returns a reference to the object it's
> called with. Think of it acting like the following code:

--
Note that robinton.demon.co.uk addresses are no longer valid.