Broke loop for user input

I'm trying to add a loop that'll keep the user from inputting incorrect values.
This part ((!(std::cin >> wchoice)) works fine, but only handles alphabeticals. But when i added the second part (wchoice != (1 || 2 || 3 || 4 || 5 || 6 || 0)) so also numerals are evaluated (list of valid), it doesnt work as i as had hoped i.e. input of 8 causes a blank line, then every input is invalid. Also a comma causes the whole program to start ignoring any input and just runs through everything. Did i incorrectly use || ?


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
  long double defineWaveLength()
{
    std::cout << "\n";
    std::cout << "Predefined sources\n";
    std::cout << "\n1 - CuKa - 1.5406A\n2 - CrKa - 2.29A\n3 - FeKa - 1.94A";
    std::cout << "\n4 - CoKa - 1.79A\n5 - MoKa - 0.71A\n6 - AgKa - 0.56A\n0 - other\n";
    std::cout << "Choose source: ";
    int wchoice;
    std::cin >> wchoice;
    std::cout << "\n";
    while((!(std::cin >> wchoice)) || (wchoice != (1 || 2 || 3 || 4 || 5 || 6 || 0)))
        {
		std::cin.clear();
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
		std::cout << "You chose poorly. \nTry again: ";
        }
    long double wl;

    switch( wchoice )
    {
    case 1: wl = 1.5406; break;
    case 2: wl = 2.29; break;
    case 3: wl = 1.94; break;
    case 4: wl = 1.79; break;
    case 5: wl = 0.71; break;
    case 6: wl = 0.56; break;
    case 0:
        {
            std::cout << "Input wavelength in angstrems" << std::endl;
            std::cin >> wl;
        }
    }

    return wl;
}
Last edited on
closed account (48T7M4Gy)
http://www.cplusplus.com/forum/beginner/194389/

Have a look here I've just shown someone something that might help. do while, rather than while do

The logic you apply may be a little more complicated but the pattern is there. somebody's already extended mine from 2 to 3 cases so you won't have any trouble by the look of it.
Last edited on
Thank you. I'll have a look.
And it helped.
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
long double defineWaveLength()
{
    std::cout << "\n";
    std::cout << "Predefined sources\n";
    std::cout << "\n1 - CuKa - 1.5406A\n2 - CrKa - 2.29A\n3 - FeKa - 1.94A";
    std::cout << "\n4 - CoKa - 1.79A\n5 - MoKa - 0.71A\n6 - AgKa - 0.56A\n0 - other\n";
    std::cout << "Choose source: ";
    int wchoice;
    long double wl;
    bool inputCheck;

    do
    {
        std::cin >> wchoice;

        if ((wchoice != (1 || 2 || 3 || 4 || 5 || 6 || 0)))
        {
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            std::cout << "\nYou chose poorly. \nTry again: ";
            inputCheck = false;
        }
        else
            {
                switch( wchoice )
                {
                case 1: wl = 1.5406; break;
                case 2: wl = 2.29; break;
                case 3: wl = 1.94; break;
                case 4: wl = 1.79; break;
                case 5: wl = 0.71; break;
                case 6: wl = 0.56; break;
                case 0:
                    {
                    std::cout << "Input wavelength in angstrems" << std::endl;
                    std::cin >> wl;
                    return wl;
                    }
                    inputCheck = true;
                }
            }
    }
    while (inputCheck == false);
}


This code works for any input. Also cleaned the if condition.
Last edited on
closed account (48bpfSEw)
This if statement looks a bit strange to me:

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


did you mean:

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



that can be shortend to:

 
if (wchoice < 0 || wchoise > 6)



or even better:

use the default of the switch case

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

switch( wchoice )
                {
                case 1: wl = 1.5406; break;
                case 2: wl = 2.29; break;
                case 3: wl = 1.94; break;
                case 4: wl = 1.79; break;
                case 5: wl = 0.71; break;
                case 6: wl = 0.56; break;
                case 0:
                    {
                    std::cout << "Input wavelength in angstrems" << std::endl;
                    std::cin >> wl;
                    return wl;
                    }
                    inputCheck = true;
                }
                break;

               default: {
                 std::cin.clear();
                 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
                 std::cout << "\nYou chose poorly. \nTry again: ";
                 inputCheck = false;

                 }
             }

Last edited on
Why is default outside of switch ?
Anyway, i tried doing it with the default moved into the switch but couldnt make it work. So i reverted back to what i posted (it worked). And now nothing works :/ The loop correctly sees invalid input and asks to correct it, but when i then input correct value it doesnt break it out of the loop. Or sometimes it doesnt work at all O_o

Reverted back to
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
long double defineWaveLength()
{
    std::cout << "\n";
    std::cout << "Predefined sources\n";
    std::cout << "\n1 - CuKa - 1.5406A\n2 - CrKa - 2.29A\n3 - FeKa - 1.94A";
    std::cout << "\n4 - CoKa - 1.79A\n5 - MoKa - 0.71A\n6 - AgKa - 0.56A\n0 - other\n";
    std::cout << "Choose source: ";
    int wchoice;
    long double wl;
    bool inputCheck;

    do
    {
        std::cin >> wchoice;

        if ((wchoice != (1 || 2 || 3 || 4 || 5 || 6 || 0)))
        {
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            std::cout << "\nYou chose poorly. \nTry again: ";
            inputCheck = false;

        }
        else
            {
                switch( wchoice )
                {
                case 1: wl = 1.5406; break;
                case 2: wl = 2.29; break;
                case 3: wl = 1.94; break;
                case 4: wl = 1.79; break;
                case 5: wl = 0.71; break;
                case 6: wl = 0.56; break;
                case 0:
                    {
                    std::cout << "Input wavelength in angstrems" << std::endl;
                    std::cin >> wl;
                    return wl;
                    }
                    inputCheck = true;
                }

            }
    }
    while (inputCheck == false);

}


And it gets stuck on VALID input. Any valid input does nothing (i.e. 1 ENTER gives a black line). Invalid then valid acts like all is invalid.
Last edited on
closed account (48T7M4Gy)
If you go outside my pattern you will have trouble unless you understand each line of it. Their is no need to verify the choice is within range because the switch control default case handles that. All you have to ensure is two things. One is whether all work in the loop is finished, and the other is whether the input is an integer and not a character or string, in which case the stream has to be cleared along with the error reset.
Changing my switch to yours causes the compiler to report:

C:\C++\Crystal\crystal_datainput.cpp|51|error: case label not within a switch statement

Line 51 is 34 here. That's default
Here's the whole code, maybe i did something wrong.
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
long double defineWaveLength()
{
    std::cout << "\n";
    std::cout << "Predefined sources\n";
    std::cout << "\n1 - CuKa - 1.5406A\n2 - CrKa - 2.29A\n3 - FeKa - 1.94A";
    std::cout << "\n4 - CoKa - 1.79A\n5 - MoKa - 0.71A\n6 - AgKa - 0.56A\n0 - other\n";
    std::cout << "Choose source: ";
    int wchoice;
    long double wl;
    bool inputCheck;

    do
    {
        std::cin >> wchoice;

            switch( wchoice )
                {
                case 1: wl = 1.5406; break;
                case 2: wl = 2.29; break;
                case 3: wl = 1.94; break;
                case 4: wl = 1.79; break;
                case 5: wl = 0.71; break;
                case 6: wl = 0.56; break;
                case 0:
                    {
                    std::cout << "Input wavelength in angstrems" << std::endl;
                    std::cin >> wl;
                    return wl;
                    }
                    inputCheck = true;
                }
                break;

               default: {
                 std::cin.clear();
                 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
                 std::cout << "\nYou chose poorly. \nTry again: ";
                 inputCheck = false;

                 }
             }
    }
    while (inputCheck == false);
}


I do understand that cin has to be cleared after incorrect input as it stores it in a buffer.
I am unsure how to check if everything within a loop was finished.
Last edited on
closed account (48T7M4Gy)
Which one is line 51, because that's where it is saying the error is.
Fixed it with a break; after switch ends.
closed account (48T7M4Gy)
All good. Cya.
Topic archived. No new replies allowed.