3

I just started learning c++ and is learning topics related to cin, cin.get. In one of my assignments, the requirement is this:

Write a program that reads in a list of integer numbers and prints the largest and the smallest number.

You can assume that the the user's input is always valid.

You can assume that the numbers in the list are separated by one space character and that the character following the last number in the list is the newline character .

Implement a loop in which the above actions are repeated until the user requests to quit.

The code I came up with is:

using namespace std;
int main()
{ 

    char ch = ' ';
    int max=0;

    do
    {
        int x;
        cin >> x;
        ch = cin.get();
        if (max = 0) { max = x; };
        if (x > max) { max = x; };
    } while (ch != '\n');
    cout << "maximum=" << max << endl;
    return 0;
}

I was expecting to have this return the maximum of the numbers in the list. But it turned out only to return the last integer in the list.

I also don't quite get why the line:

cin >> x;
ch = cin.get();

makes the program able to accept a list of numbers. Isn't cin suppose to ask the user to input some stuff, as well as cin.get? In another word, shouldn't the user encounter input two times? But why is it when I run I am only asked to input once?

After some adjustment using the comments in this post, I was able to come up with the code as such:

int main()

{

cout << "Enter the list of integer numbers: ";

char ch = ' ';

int max=0;
int min = 0;

do
{
    int x;

    cin >> x;

    ch = cin.get();

    if (max == 0) { max = x; };
    if (x > max) { max = x; };

    if (min == 0) { min = x; };
    if (x < min) { min = x; };
} while (ch != '\n');



cout << "maximum=" << max << endl;
cout << "minimum=" << min << endl;
return 0;

My final question is: How can I satisfy the requirement of this assignment "Implement a loop in which the above actions are repeated until the user requests to quit."

Rico
  • 93
  • 1
  • 8
  • 3
    `if (max = 0) { max = x; };` is a bug. Note that `==` is comparison. `=` is assignment. – drescherjm Apr 21 '19 at 02:13
  • `cin >> x;` skips all whitespace until it finds and reads an integer from the stream (or fails unchecked and the whole program falls into an infinite loop). It will stop reading when it hits something that cannot be an `int`. Presumably this will be a space, a comma, or something, but it could be the end of the stream (and the program falls into the same infinite loop). `ch = cin.get();` will read the character that stopped the `int` from the stream. If it found the end of the line, it exits the loop. – user4581301 Apr 21 '19 at 02:14
  • I suggest using something like [option 2 in this answer](https://stackoverflow.com/a/7868998/4581301) instead. – user4581301 Apr 21 '19 at 02:15

1 Answers1

1

Your initial problem lies with the code:

if (max = 0) { max = x; };

The single = is assignment, not comparison. What is does is set max to zero, then use that zero as a truth value, which always equates to false.

Hence the effect is that max will be set to zero, and the body of the if will never be executed.

You need to use == for comparison.


In terms of looping until user indicates they want to quit, you can use the fact that invalid input can be detected with the >> extraction operator.

As an aside, since extraction of an integer first skips white-space, you don't have to worry about handling spaces and newlines at all, they'll naturally be skipped as part of the "get next integer" operation.

By way of example, the following complete program will exit when you enter q (or any invalid number for that matter, though if you enter 47q, it will handle the 47 first before exiting on the q):

#include <iostream>

int main () {
    int inVal;
    while (true) {
        std::cout << "Enter number (q to quit): ";
        if (! (std::cin >> inVal)) break;
        std::cout << inVal << '\n';
    }
    std::cout << "Done\n";
}

A sample run follows:

Enter number (q to quit): 1
1
Enter number (q to quit): 2
2
Enter number (q to quit): 3
3
Enter number (q to quit): 55
55
Enter number (q to quit): 42
42
Enter number (q to quit): q
Done

So you can use that to detect non-numeric input and act accordingly:

#include <iostream>

int main () {
    int inVal, maxVal, minVal, firstTime = true;
    while (true) {
        std::cout << "Enter number (q to quit): ";
        if (! (std::cin >> inVal)) break;
        if (firstTime) {
            firstTime = false;
            minVal = maxVal = inVal;
        } else {
            if (inVal > maxVal) {
                maxVal = inVal;
            }
            if (inVal < minVal) {
                minVal = inVal;
            }
        }
    }
    if (firstTime) {
        std::cout << "*** You didn't enter any numbers.\n";
    } else {
        std::cout << "*** Minimum was " << minVal
                  << ", maximum was " << maxVal << ".\n";
    }
}

Some sample runs of that:

pax:~> ./testprog
Enter number (q to quit): q
*** You didn't enter any numbers.

pax:~> ./testprog
Enter number (q to quit): 1
Enter number (q to quit): q
*** Minimum was 1, maximum was 1.

pax:~> ./testprog
Enter number (q to quit): 9
Enter number (q to quit): 8
Enter number (q to quit): -3
Enter number (q to quit): 7
Enter number (q to quit): 5
Enter number (q to quit): 42
Enter number (q to quit): q
*** Minimum was -3, maximum was 42.

I'm assuming here the allowed assumption that the user input is always valid applies to the allowed characters being input (such as "no 47q allowed"), and that, if the marker complains that you're meant to stop on the first newline, you can argue that any number after that newline constitutes invalid data, and is therefore an invalid test case.

In the real world, you'd write your code robustly enough to handle edge cases like that but I suspect it's not necessary for educational work (even if it may earn you some extra marks).

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953