Need help with my loop, input problem

Hi, so I have my program almost complete, it's supposed to draw a hollow box from one number input in a range of 3-50. For some reason when I input a number it has two prompts and then does the calculations, in other words I have to put in a number twice for it to actually do anything. I suspect it has something to so with my top while loop but I can't find the problem. I've re-read my book but it doesn't cover much about excluding certain characters very well. The idea of the while loop after the do loop is to catch any non-number input. I couldn't find any posts on how to format my code nicely but I'll just copy/paste for now.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <string>
using namespace std;

int main()
{
    const char CORNER = '+';
    const char TOP_OR_BOTTOM = '-';
    const char SIDES = '|';
    const char WHITE_SPACE = ' ';

    char playAgain;

    int minSize = 2;
    int maxSize = 50;
    int smallestSquare = 2;

    do
    {
        int size = 0;
        int counter = 0;
        int counter2 = 0;
        int counter3 = 0;

        cout << "Side size = ";
        cin >> size;
        // Validation loop
        while (!(cin >> size))
        {
            cin.clear();
            string nonNumber;
            getline(cin, nonNumber);
            cout << "OOPS! Looks like you typed some bad data here!\n";
            cout << "The acceptable dimension should range from 3 to 50, so choose carefully...\n";
            cout << "Side size = ";
            cin >> size;
        }
        // Print out side rows after top is made, invariant is size, variant is the counter
        for (counter = 0; counter < size; counter++)
        {
            // If it's top or bottom line print out corner
            if (counter == 0 || counter == size - 1)
            {
                cout << CORNER;
                for (counter2 = 0; counter2 < size - smallestSquare; counter2++)
                {
                    cout << TOP_OR_BOTTOM;
                }
                cout << CORNER << "\n";
            }

            // Print out sides
            else
            {
                cout << SIDES;
                for (counter3 = 0; counter3 < size - smallestSquare; counter3++)
                {
                    cout << WHITE_SPACE;
                }
                cout << SIDES << "\n";
            }
        }
        //
        cout << "To try my shape generator program again type Y for Yes and N for No: ";
        cin >> playAgain;
    } while ('Y' == toupper(playAgain));

    return 0;
}
Last edited on
Quick and dirty refactor:

25
26
27
28
      // cout << "Side size = ";
      // cin >> size;
      // Validation loop
      while (cout << "Side size = ", !(cin >> size))

And then delete/comment out lines 35-36.
Wow! it works now, that bit of code "(cout << "Side size = "," seems like such a small addition to the code, I'm not sure how it works. To me all that's saying is while "cout << side..." is true print it out, and it can always be true. So, how is this one statement so important?

I just came across this trying to google that code you gave me. (I'm surprised I found the exact same problem through google by the way). Basically !(cin >> size)) is acting as another prompt!

https://stackoverflow.com/questions/39541141/about-while-cinx/39541342
Last edited on
Using the comma operator in the while evaluation is subtle and powerful.

The Comma Operator: https://www.tutorialspoint.com/cplusplus/cpp_comma_operator.htm

Comma in C and C++: https://www.geeksforgeeks.org/comna-in-c-and-c/
That's weird that it dumps the previous values before the comma. Maybe it's just to save memory? So in the while loop you provided, the fist expression is always true? how does it still print out if it's discarded when it gets to !(cin >> size))? and then the last expression is always true as long as I put in a non-number? That's how my program behaves anyway...
> how does it still print out if it's discarded

A discarded-value expression is an expression that is used for its side-effects only. The value calculated from such expression is discarded. Such expressions include the full expression of any expression statement, the left-hand operand of the built-in comma operator, or the operand of a cast-expression that casts to the type void.
https://en.cppreference.com/w/cpp/language/expressions#Discarded-value%20expressions


In the expression statement std::cout << "hello world" ;, the expression std::cout << "hello world" is a discarded-value expression. It is evaluated and its side-effect is that something is printed out on stdout, but its result is discarded.


> and then the last expression is always true as long as I put in a non-number?

On bad input, the stream goes into a failed state. In the loop, the expression is contextually converted to bool. https://en.cppreference.com/w/cpp/language/implicit_conversion#Contextual_conversions

The loop could also be written as while (cout << "Side size = " && !(cin >> size)) { ...


Ok, thanks!
Topic archived. No new replies allowed.