not understanding how cin value is behaving

I have what is probably a simple question but I am unable to find the answer here or in any of the other documentation I have been referring to.

In short, I am working on a variation of the Dungeon Crawl exercise. I have chosen to accept inputs of U/D/L/R (or u/d/l/r) and based on the input, move the character. In this example the character representation cycles through the alphabet and the goal has to be reached before the alphabet ends. (Things with letters interest my 3-year old son).

I am using cin >> for input.

While my code handles non U/D/L/R values appropriately, it does not behave as I expected when something like UD or UU or even UUUDDDUUULLL are entered. Rather than treating such input as an incorrect input, it acts as if I had entered U, <enter>, D, <enter> (in the case of UD for example). To my suprise, the letter displayed (the character) even advances as if the values had all been input separately.

I have read the articles on cin and see that there are probably better ways to handle user input that I will soon learn, but I would greatly appreciate an idea of what concepts I need to study for this behavior to make sense.

I think I now understand how to limit the input to one character but I still can't understand what I see.

If it will make it clearer, I have the code listed below. If what is below is more than neccessary to illustrate this question, please say so and I will trim down any future questions.

I know I was a little lazy with the output formatting but it was quick and looks clean in a small console window.

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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//
//Make a program that outputs a simple grid based gameboard 
//to the screen using either numbers or characters.

#include<iostream>

using namespace std;

main()
{

int pass = 1;
char move;
int charlocation = 1;
char board[102]; 

for (int g=0;g<10;g++)
{cout << endl;}
int q=0;    // counting variable for board output

 do
{
    char alphabet[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
    int a=1;    // counting variable for board output
    int i=0;    // counting variable for board output
    int b=0;    // counting variable for board output
    
    
/* loops to display an array[100] ten values per line (the board).
 Empty spaces represented as '.'       
 */      
        { for (b=0;b<100;b++)
            {
            board[b] = '.';
            }
        board[charlocation] = alphabet[q];  // the player's current location
        q=(q+1);
        board[100] = '!';           // the goal
        
                while (i<101)
                {
                    {
                    for (i=a;i<(a+10);i++)
                    cout << board[i];
                    cout << endl;
                    }                   
                    a= (a+10);
                } 
        }
    
// prompt for movement

cout << endl << endl;
cout << "Choose a direction to move:" << endl;
cout << "<U>p, <D>own, <L>eft, <R>ight" << endl;
cin >> move;
for (int h=0;h<10;h++)
{
cout << endl;}  
    
    if (move == 'U' || move == 'u')  
        {
            if 
            (charlocation <11 && charlocation >0) //limits upward movement
                {
                charlocation = 110;
                pass = 0;
                }
        charlocation = (charlocation - 10); // assigns upward movement
        }
        
    else if (move == 'D' || move == 'd')
            {
            if 
            (charlocation <100 && charlocation >90)//limits downward movement
                {
                charlocation = 90;
                pass = 0;
                }
        charlocation = (charlocation + 10); //assigns downward movement
            }
            
            
    else if (move == 'L' || move == 'l')
            {
            if 
            (charlocation%10 ==1)//limits leftward movement
                {
                charlocation = 101;
                pass = 0;
                }
        charlocation = (charlocation - 1);//assigns leftward movement
            }
    
    
    else if (move == 'R' || move == 'r')
            {
            if 
            (charlocation%10 ==0)//limits rightward movement
                {
                charlocation = 99;
                pass = 0;
                }
        charlocation = (charlocation + 1);//assigns rightward movement
            }
      
      else  {
            cout << "That was not a valid input.  please try again." << endl;
            q = (q-1);
            }

}        
   while ((charlocation != 100) && (q != 26));
if (q==26)
{pass = 2;}
for (int z=0; z<100; z++)
cout << endl;

switch (pass)
    {
    case 0: cout << "YOU LOSE!!!  YOU MOVED OFF THE BOARD!!!" << endl;
    break;
    case 1: cout << "YOU WIN!!!!!" << endl;
    break;
    case 2: cout << "YOU LOSE!!!  YOU RAN OUT OF LETTERS!!!" << endl;
    break;
    }

for (int y=0; y<10; y++)
cout << endl;

    system("pause");
    return 0;
}
Last edited on
That's because you are using the >> operator into a character, which means it will read the one character and ignore anything else, and since input is a buffer, the other characters are left. For example:

Input = "UD\n"
cin >> some_char;
Now some_char = 'U'
and Input = "D\n"

So the next time around it tries to get a character and sees the 'D' then continues. If you want them to be enter delimited, you will have to read an entire line (use std::getline()) and then compare the string as opposed to a single character.
While finally going back to the "Don't use: system("pause"); " thread and actually trying to understand the later pages of it, I saw Duoas' explanation about clearing the buffer. I then remembered Grey Wolf's response earlier today to Plantking's question.

So I assumed if I inserted std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' ); right after line 56 in the above code, the behavior that I was experiencing would vanish.

And while it did, it would still accept UU, UDDDU etc., but it only seemed to register the first character. That confused me until I just read what you wrote, now it makes perfect sense.

Thanks very much.


Topic archived. No new replies allowed.