do while loop, invalid user inputs....

Hello,

So I am trying to get this loop to take in values and check if they are within my requirements. The input will be invalid if the number of lines(lines in a table I am going to create)is less than three or greater than 25. Also, input will be invalid if it is negative. The loop will work for valid entries, and initially for incorrect number of lines(calculates number of lines with for loop and counter)but than after it loops again it wont work for a valid case.

This is the code:

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
 #include <iostream>	//header containing cout and cin
#include <string>
#include <iomanip>

using namespace std;  //introduces namespace std needed to use cout and cin

int main()
{
	string DIM,invalid,start,end,DIMtable,UNIT1table,UNIT2table;
	double factor,inc,sum=0,convert1,val1,val2;
	int dec1,dec2,lines,lastval,count=0,width1,width2,tablength1,tablength2;
	bool userinput;
	
cout << "Enter length, mass or time: ";
cin >> DIM;
do
	{
	if(DIM == "length" || DIM == "mass" || DIM == "time")
	{
	cout << "\nEnter the starting value: ";
	cin >> val1;
	cout << "\nEnter the ending value: ";
	cin >> val2;
	cout << "\nEnter the increment value: ";
	cin >> inc;
	cout << "\nEnter the starting value decimal places: ";
	cin >> dec1;
	cout << "\nEnter the ending value decimal places: ";
	cin >> dec2;
	}
	for(double i=val1; i<=val2; i+=inc)
		count++;
	if(count < 3 || count > 25)
	{
	cout << "\n    INVALID ENTRY - TOO LITTLE OR TO MANY LINES IN THE TABLE  - RESTARTING\n";
	cout << "\n    ENTER STARTING, ENDING AND INCREMENT VALUES THAT PRODUCE 3 - 25 LINES\n";
	userinput = true;
	}
	else if(val1 < 0 || val2 < 0 || inc < 0 || dec1 < 0 || dec2 < 0) 
	{
	cout << "\n    INVALID ENTRY - ALL VALUES MUST BE >= 0 - RESTARTING\n";
	userinput = true;
	}
	else
	{
	userinput = false;
	}
	}while(userinput);
	
	cout << "loop has been exited";
	return 0;
}


Here is the valid output exiting the loop:

Enter length, mass or time: length

Enter the starting value: 0

Enter the ending value: 10

Enter the increment value: 1

Enter the starting value decimal places: 1

Enter the ending value decimal places: 1
loop has been exited


Here is the invalid and valid not exiting:

Enter length, mass or time: length

Enter the starting value: 0

Enter the ending value: 100

Enter the increment value: 1

Enter the starting value decimal places: 1

Enter the ending value decimal places: 1

    INVALID ENTRY - TOO LITTLE OR TO MANY LINES IN THE TABLE  - RESTARTING

    ENTER STARTING, ENDING AND INCREMENT VALUES THAT PRODUCE 3 - 25 LINES

Enter the starting value: 0

Enter the ending value: 10

Enter the increment value: 1

Enter the starting value decimal places: 1

Enter the ending value decimal places: 1

    INVALID ENTRY - TOO LITTLE OR TO MANY LINES IN THE TABLE  - RESTARTING

    ENTER STARTING, ENDING AND INCREMENT VALUES THAT PRODUCE 3 - 25 LINES

Enter the starting value:

The problem is that you forget to reset count to zero at the beginning of the loop. Thus, when you enter 100 as the ending value, count thus becomes 100. But when it goes back to the beginning of the loop and asks you for the starting value again, count is still 100 and is incremented to 110 at the end of the loop, which will always fail.

To fix this, you need to set count = 0 at the beginning of the do/while.
Firstly, Let’s remove the unused variables and let’s see what’s left:
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
#include <iomanip>
#include <iostream>
#include <string>


int main()
{
    std::cout << "Enter length, mass or time: ";
    std::string DIM;
    std::cin >> DIM;

    bool userinput;
    do {
        double val1;
        double val2;
        double inc;
        int dec1;
        int dec2;
        if (DIM == "length" || DIM == "mass" || DIM == "time") {
            std::cout << "Enter the starting value: ";
            std::cin >> val1;
            std::cout << "Enter the ending value: ";
            std::cin >> val2;
            std::cout << "Enter the increment value: ";
            std::cin >> inc;
            std::cout << "\nEnter the starting value decimal places: ";
            std::cin >> dec1;
            std::cout << "\nEnter the ending value decimal places: ";
            std::cin >> dec2;
        }
        // Are you sure you don’t need an 'else' here?

        int count = 0;
        for (double i = val1; i <= val2; i += inc) {
            count++;
        }

        if (count < 3 || count > 25)  {
            std::cout << "\n    INVALID ENTRY - TOO LITTLE OR TO MANY LINES IN "
                         "THE TABLE  - RESTARTING\n";
            std::cout << "\n    ENTER STARTING, ENDING AND INCREMENT VALUES "
                         "THAT PRODUCE 3 - 25 LINES\n";
            userinput = true;
        }
        else if (val1 < 0 || val2 < 0 || inc < 0 || dec1 < 0 || dec2 < 0)  {
            std::cout << "\n    INVALID ENTRY - ALL VALUES MUST BE >= 0 - "
                         "RESTARTING\n";
            userinput = true;
        }
        else {
            userinput = false;
        }
    } while (userinput);
    
    std::cout << "loop has been exited\n";
}


Now it looks like you’re only checking the user input validity.
So, make this become a function, then break it into parts and move them into other functions too.
For example, you could have a couple of functions that check if the user has entered a positive integer (or double) and loop until they get one. You could than use them this way:
1
2
3
4
std::cout << "Enter the starting value: ";
double start_val = getPositiveDouble();
// ...
int inc = getPositiveInteger(); 


Once your code is easier to deal with, you can improve it.
(For example, you won’t needed to ask dec1 and dec2 if you had already reckoned count it’s too little ot too big).
@TheToaster, I knew i had to reset that and for whatever reason I was thinking of every command but that one....I don't think I will ever forget that again, that fixed the issue. Thanks for your time.

@Enoizat, I was just looking for that simple fix, but I do see what you are saying about the functions, that is a good idea, and would simplify the code even more. Learning everyday...I will take that on board. Thanks for you time.

Topic archived. No new replies allowed.