Use of cin.clear() and cin.ignore()

I have this condition for restricting inputs besides integers between 0-7. The purpose of this code is really to block out letters. Now I need to do something similar when the possible inputs are integers between 0-255.

1
2
3
4
			if (index != 0 || 1 || 2 || 3 || 4 || 5 || 6 || 7) {
				cin.clear();
				cin.ignore();
			}


This is the entire case for my switch:

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
case Data:

			cout << "Enter buffer index (0-7): ";
			cin >> index;
			if (index != 0 || 1 || 2 || 3 || 4 || 5 || 6 || 7) {
				cin.clear();
				cin.ignore();
			}
				if (index == 0) {
					cout << "buffer[" << index << "] = ";
					cin >> num;
					cout << "\n";
					if (num >= 0 && num <= 255) {
						index0 = num;
					}
					else {
						cout << "\nInvalid option, please try again!" << endl;
					}
				}
				else if (index == 1) {
					cout << "buffer[" << index << "] = ";
					cin >> num;
					cout << "\n";
					if (num >= 0 && num <= 255) {
						index1 = num;
					}
					else {
						cout << "\nInvalid option, please try again!" << endl;
					}
				}
				else if (index == 2) {
					cout << "buffer[" << index << "] = ";
					cin >> num;
					cout << "\n";
					if (num >= 0 && num <= 255) {
						index2 = num;
					}
					else {
						cout << "\nInvalid option, please try again!" << endl;
					}
				}
				else if (index == 3) {
					cout << "buffer[" << index << "] = ";
					cin >> num;
					cout << "\n";
					if (num >= 0 && num <= 255) {
						index3 = num;
					}
					else {
						cout << "\nInvalid option, please try again!" << endl;
					}
				}
				else if (index == 4) {
					cout << "buffer[" << index << "] = ";
					cin >> num;
					cout << "\n";
					if (num >= 0 && num <= 255) {
						index4 = num;
					}
					else {
						cout << "\nInvalid option, please try again!" << endl;
					}
				}
				else if (index == 5) {
					cout << "buffer[" << index << "] = ";
					cin >> num; 
					cout << "\n";
					if (num >= 0 && num <= 255) {
						index5 = num;
					}
					else {
						cout << "\nInvalid option, please try again!" << endl;
					}
				}
				else if (index == 6) {
					cout << "buffer[" << index << "] = ";
					cin >> num;
					cout << "\n";
					if (num >= 0 && num <= 255) {
						index6 = num;
					}
					else {
						cout << "\nInvalid option, please try again!" << endl;
					}
				}
				else if (index == 7) {
					cout << "buffer[" << index << "] = ";
					cin >> num;
					cout << "\n";
					if (num >= 0 && num <= 255) {
						index7 = num;
					}
					else {
						cout << "\nInvalid option, please try again!" << endl;
					}
				}
				else {
					cout << "\nInvalid option, please try again!" << endl;
				}

			break;


Could someone please show me how I would force all inputs of any type the are not integers between 0-255 to break to the default?
Last edited on
Using clear()/ignore() is useful only in case of an erroneous input. Only when the wrong type (character like 'A' instead of integer) is entered. See this for an example how to correctly use it:

http://en.cppreference.com/w/cpp/io/basic_istream/ignore

This

if (index != 0 || 1 || 2 || 3 || 4 || 5 || 6 || 7)

is wrong / always true, because any expression is true if != 0.

http://www.cplusplus.com/doc/tutorial/control/
http://en.cppreference.com/w/cpp/language/if

The correct syntax would be if (index != 0 || index != 1 || index != 2 || ...), but this would be logically wrong / always true (use && instead of ||).

Do not use clear()/ignore() if the stream does not report an error.
The reason that I used the index if statement the way I did was because I was getting an infinite loop if the input was a character. That if statement did resolve that issue. The current issue is that I need to prevent an infinite loop at the next stage (where the user is prompted to enter an integer between 0-255).
Here's one way to do it:
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
    bool error = false;
    
    int index = -1;
    do {
        if (error)
        {
            cout << "\nInvalid index, please try again!" << endl;
            cin.clear();
            cin.ignore(100, '\n'); 
        }
        
        cout << "Enter buffer index (0-7): ";
        cin >> index;        
        
        if (!cin || index <0 || index > 7)
        {
            error = true;
        }           
        else
        {
            error = false;
        }
        
    } while (error);


    error = false;
    int num = -1;
    do {
        if (error)
        {
            cout << "\nInvalid option, please try again!" << endl;
            cin.clear();
            cin.ignore(100, '\n'); 
        }        
        cout << "buffer[" << index << "] = ";
        cin >> num;

        error =  (!cin || num < 0 || num > 255);

    } while (error); 
        
    
    switch (index)
    {
        case 0: index0 = num; break;
        case 1: index1 = num; break;
        case 2: index2 = num; break;
        case 3: index3 = num; break;
        case 4: index4 = num; break;
        case 5: index5 = num; break;
        case 6: index6 = num; break;
        case 7: index7 = num; break;
    }


The first time the loop is executed, at line 5 the error flag will be false, so the code inside the if statement will not be executed. After the cin at line 13, a check is made for failed input (non-numeric characters) or out of range value being entered. The error flag is set accordingly. The loop will repeat until correct input is entered.

The second block of code from line 27 to 41 is similar. Here I used a more concise assignment statement at line 39. This works exactly the same as the if/else in the earlier code, but is less verbose.

Finally, the original code had a lot of repetition, which I've cut down to the switch-case at line 44 to 54. Actually I would replace all the separate variables index0 to index7 with an array value[8] and then that block becomes simply the single line
 
    value[index] = num;


Last edited on
Topic archived. No new replies allowed.