Infinite loop when a letter is an Input, any fix?

Hi, I got this problem where the program just infinitely loops when a letter is an input instead of a number. it happens in line 36-76 and same as the next one.

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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include <iostream>

using namespace std;

int main()
{
    string name, sx, sex, team, final_conf;
    int alt_all, alt1, alt2, alt3, male_teamc, female_teamc, alt_in;

    string error_out= "\n\n>>>>> INVALID INPUT!! <<<<<\n     Please Try Again.\n\n";
    alt_all=1; //An actual switch for all the codes (not switch case)

    while(alt_all==1)
    {
        alt_in=1;

        while (alt_in==1)
        {
            alt1=1; //For door 1 define and reset
            alt2=1; //For door 2 define and reset
            alt3=1; //For door 3 define and reset
            name.clear(); //Clears name container
            cout<< "====================================\n"
                << "      Intramurals Registration"
                << "\n====================================\n\n";
            cout<< "Please enter your Fullname below.\n"
                << "\nFull Name: ";
            getline(cin, name);
            cout<< "\nPlease input your sex (M/F): ";
            cin >> sx;

            // Validation and team choice

                if (sx=="M" || sx=="m")
                {
                    sex="Male";
                    while (alt1==1)
                    {
                    cout<< "\n\nPlease choose the number of the corresponding team you preferred: "
                        << "\n\n\t1. Jaguar"
                        << "\n\t2. Eagle"
                        << "\n\t3. Crocodile";
                    cout<< "\n\nYour input: ";
                    cin >> male_teamc;

                        switch (male_teamc)
                        {
                        case 1:
                            {
                                team="Jaguar";
                                alt1=2; //alt1=2 kills the whole while loop he's in and proceed to next codes
                                alt_in=2;
                                break;
                            }
                        case 2:
                            {
                                team="Eagle";
                                alt1=2;
                                alt_in=2;
                                break;
                            }
                        case 3:
                            {
                                team="Crocodile";
                                alt1=2;
                                alt_in=2;
                                break;
                            }
                        default:
                            {
                                cout<< error_out; //No alt1=2, we keep alt1=1 so loop continues
                                break;
                            }
                        }
                    }
                }
                else if (sx=="F" || sx=="f")
                {
                    sex="Female";
                    while (alt2==1)
                    {
                    cout<< "\n\nPlease choose the number of the corresponding team you preferred: "
                        << "\n\n\t1. Barbie"
                        << "\n\t2. Prada"
                        << "\n\t3. Payless";
                    cout<< "\n\nYour input: ";
                    cin >> female_teamc;

                        switch (female_teamc)
                        {
                        case 1:
                            {
                                team="Barbie";
                                alt2=2; //alt2=2 kills the whole while loop he's in and proceed to next codes
                                break;
                            }
                        case 2:
                            {
                                team="Prada";
                                alt2=2;
                                break;
                            }
                        case 3:
                            {
                                team="Payless";
                                alt2=2;
                                break;
                            }
                        default:
                            {
                                cout<< error_out; //No alt2=2, we keep alt1=1 so loop continues
                                break;
                            }
                            }
                        }

                    }
                    else
                    {
                        cout<< "Sorry I did not quite get that.\n"
                            << "Please make sure you type either M or F only.";
                    }
        }



                        // PART 3
                        while(alt3==1)
                        {
                                cout<< "\n\nYour name is " + name + ". Your sex is " + sex
                                    << ". And you have been assigned to Team " + team + ".";
                                cout<< "\n\nIs that correct? (Y/N): ";
                                cin>> final_conf;
                                cin.ignore(); //Used to fix skipped getline on line 24, getline() thinks final_conf if for him, lol
                            if (final_conf=="Y"||final_conf=="y")
                            {
                                cout<< "\n\n========================================\n"
                                    << "      You have been Registered!!"
                                    << "\n========================================\n\n";
                                cout<< "Registered Data: ";
                                cout<< "\n\nYour name is " + name + ". Your sex is " + sex
                                    << ". And you have been assigned to Team " + team+".\n\n";
                                    alt_all=2; //Kills the entire while loop, technically ends program
                                    alt3=2; //Kills this loop he's in
                            }
                            else if (final_conf=="N"||final_conf=="n")
                            {
                                cout<< "\n\nCanceled!\nPlease restate your information again.\n\n";
                                alt3=2; //Kills this loop he's in, but loops back on top since alt_all is still =1
                            }
                            else
                            {
                                cout<< error_out;
                                // Loop from PART 3
                            }
                        }
    }
   return 0;
}
Last edited on
just infinitely loops when a letter is an input instead of a number


Yes. That is by design.

L44 attempts to do a stream extract to the int male_teamc. However if a non-int is tried to be extracted then the stream enters a fail state and the extraction is not done. The stream remains in the fail state until the error is cleared. No input can be obtained when in fail state. Then the bad input needs to be removed from the stream.

This is an advanced function that will get a number from the keyboard and deals with invalid input.

L43, 44 would be replaced by:

 
male_teamc = getInp("Your input: ");


You'll also need these includes:

1
2
3
4
#include <limits>
#include <type_traits>
#include <iostream>
#include <cctype> 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// This function goes before main()
template<typename T = int>
typename std::enable_if_t< std::is_integral_v<T>, T>
getInp(const std::string& prm)
{
	const auto notsp {[&]() {while (std::isspace(static_cast<unsigned char>(std::cin.peek())) && std::cin.peek() != '\n') std::cin.ignore(); return std::cin.peek() != '\n'; }};
	T n {};

	while ((std::cout << prm) && (!(std::cin >> n) || notsp())) {
		std::cout << "Invalid input. Not a(n) " << typeid(T).name() << '\n';
		std::cin.clear();
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	}

	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	return n;
}


As a simple test program:

1
2
3
4
5
6
7
8
9
10
11

// includes assumed

int main()
{
	int a {};

	a = getInp("Enter a number: ");

	std::cout << a << '\n';
}



Enter a number: 98u
Invalid input. Not a(n) int
Enter a number: u89
Invalid input. Not a(n) int
Enter a number: 98.98
Invalid input. Not a(n) int
Enter a number: 98
98

Last edited on
I haven't understood a thing. I'm a beginner and I am having that problem, is there any beginner fix?
Anywhere your stream may fail, you should have:

1
2
3
4
5
if (cin.fail())
    {
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n'); 
    }


If you try to cin into an integer, and you get bad input, then you can detect the stream failure through fail(), and then you clear the error with clear(). Finally, you use ignore() to ignore the bad input given.

numeric_limits requires the limits library. That line will ignore all input given up to a new line character.
Topic archived. No new replies allowed.