Validating data using loops

Hey everyone! I've been working on a project for class, and this week I am supposed to add loops to validate data. I'm getting very confused! I need to add a loop to validate data this week and I have no idea where I can add that into my program. I am doing a car rental program. I thought maybe I could ask the user how old they are, and if they are under 25, they cannot rent the vehicle, but I guess that wouldn't require a loop. Can someone point me in the right direction please?? I can write the code for it myself, I am just stuck on where I can validate some data in a loop.

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
Description: Calculating car rental cost
*/

#include <iostream>
#include <iomanip>
#include <string>
#include <limits>
using namespace std;



int main()
{
	int days;
	double rentalRate;
	double totalCost;
	int carType;
	string carClass;
	char customerName[50];
	int age;

	cout << "Welcome to the car rental program! This program will allow 
                 you to" << endl; 
	cout <<	"fill out information and we will calculate the cost of 
                renting a car!" << endl;
	cout << endl;

	cout << "Please enter the name of the primary renter: ";
	cin >> customerName;

	cout << "Please enter your age";
	cin >> age;

	cout << "Please enter how many days you will need the car: ";
	cin >> days;

	cout << "Enter the car type (1- Luxury, 2- Midsize, 3- Compact): ";
	cin >> carType;

	if (carType == 1)
        {
		rentalRate = 50.;
		carClass = "Luxury";
	}
	else if (carType == 2)
        {
		rentalRate = 35.;
		carClass = "Midsize";
	}
	else if (carType == 3) 
        {
		rentalRate = 19.99;
		carClass = "Compact";
	}
	else 
        {
		cout << "Not a valid choice.";
		rentalRate = -1.;

	}

	totalCost = days * rentalRate; //calculate the cost

	if (totalCost > 0.) {
		cout << "The total cost to rent a " << carClass << " for a " 
             << days << " day rental is: " << totalCost << endl;

	}



	system("pause");

}
[/code][/code]
Last edited on
Please edit your post to put code tags around the code.
https://www.cplusplus.com/articles/jEywvCM9/
Maybe like this:
1
2
3
4
5
6
do
{
  cout << "Enter the car type (1- Luxury, 2- Midsize, 3- Compact): ";
  cin >> carType;
  // print error if input not valid
}while(carType < 1 || carType > 3);
Hello JustADream,


PLEASE ALWAYS USE CODE TAGS (the <> formatting button), to the right of this box, when posting code.

Along with the proper indenting it makes it easier to read your code and also easier to respond to your post.

http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/

Hint: You can edit your post, highlight your code and press the <> formatting button. This will not automatically indent your code. That part is up to you.

You can use the preview button at the bottom to see how it looks.

I found the second link to be the most help.


I will start with the program.
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
#include <iostream>
#include <iomanip>  // <--- std::fixed, std::setprecision().
#include <limits>
#include <string>

using namespace std;

int main()
{
    int days{};
    double rentalRate{ 19.99 };
    double totalCost{};
    int carType{};
    string carClass{ "Compact" };
    std::string customerName;
    //char customerName[50];
    int age{};

    std::cout << std::fixed << std::setprecision(2);

    cout <<
        "\n Welcome to the car rental program! This program will allow you to\n"
        " fill out information and we will calculate the cost of renting a car!\n\n";

    cout << "Please enter the name of the primary renter: ";
    cin >> customerName;

    cout << "Please enter your age: ";
    cin >> age;

    cout << "Please enter how many days you will need the car: ";
    cin >> days;

    cout << "Enter the car type (1- Luxury, 2- Midsize, 3- Compact): ";
    cin >> carType;

    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.

    if (carType == 1)
    {
        rentalRate = 50.0;
        carClass = "Luxury";
    }
    else if (carType == 2)
    {
        rentalRate = 35.;
        carClass = "Midsize";
    }
    //else if (carType == 3)
    //{
    //    rentalRate = 19.99;
    //    carClass = "Compact";
    //}
    else
    {
        cout << "Not a valid choice.";
        rentalRate = -1.;
    }

    totalCost = days * rentalRate; //calculate the cost

    if (totalCost > 0.)
    {
        cout << "\nThe total cost to rent a " << carClass << " for a "
            << days << " day rental is: " << totalCost << "\n\n" << endl;
    }

    system("pause");
}

First notice I removed some unnecessary blank lines and added some others.

I added the 3 include files. "string" is necessary, but the other 2 can be optional although I would start getting use to "iomanip". This only work with "iostream" to manipulate the output and sometimes input.

It is always a good idea to initialize your variables. The empty{}s, available from C++11 on and known as the uniform initializer, make it very easy to initialize the variables. The empty{}s will set the integral type variables to 0 and floating point variables to 0.0.

Strings are empty when defined and do not need initialized unless you are doing something as you see in the code, line 14.

To answer your question. There are several placed where you could use a loop.

First: taking lines 21 - 68 you could use a do/while or while loop to keep the program running until you do something to cause it to end.

Next is line 26. This is called formatted input. One part of this is that it picks up on the variable type, in this case a string", and will allow any character typed on the keyboard to be stored in the variable "customerName". The other part of formatted input is that it will extract from the input buffer until it finds a space or new line "\n" whichever comes FIRST. That means given a name of "John Smithe" only "John" will be stored in the variable and "Smithe\n" will be left in the input buffer.

Since "customerName" should be defined as a "std::string" you can use
std::getline(std::cin, customerName);. As unformatted input it will extract everything including the "\n", which it will dis-guard, and store what is left in the variable.

Lines 28 and 29 are a good candidate for a loop. But broaden your thinking. Validation is more than just checking if a number is in range. In addition to what I said earlier here the formatted input cin >> age;. "cin" is expecting a whole number to be entered. Anything that is not a number will cause "cin" to fail and be unusable the rest of the program.

Most of the time you have to anticipate problems.

Something that you could do is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
do
{
    cout << "Please enter your age: ";
    cin >> age;

    if (!std::cin || age < 25)
    {
        if (!std::cin)
        {
            std::cout << "\n Invalid input! Must be a number.\n";

            std::cin.clear();  // <--- Resets the state bits on the stream.
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>. Clears the input buffer.
        }
        else if (age < 25)
        {
            std::cout << "\n     You Must be at least 25 to rent a car.\n";
        }
    }
} while (age < 25);

The first part of line 6 checks to see if "cin" has failed. This way it does not matter what state bit is set it will evaluate to true.

This will stay in the loop until "age" has a valid number.

The same concept can be used for "days" and "carType".

Line 55 I put there for now because you will need to clear the input buffer before the next "getline". Also based on putting most of "main" in a do/while loop.

The if/else if statements. If you initialize the variables "rentalRate" and "carClass" as I did you will only need to check for 1 or 2. Since the variables are already set the check for (3) is not needed and the "else" could either be reworked or eliminated.

The line if (totalCost > 0.0). Although (0.) may work the more proper way of writing this is (0.0). And the same would be true for the others as you can see in line 41. Since the variables "rentalRate" is initialized with a starting value and "days" would not leave the loop until it is at least (1) the if statement would always be true and therefore not really much use.

Just so you know. Since "totalCost" should always have a value greater than zero you could just write: if (totalCost). I think should work with a "double".

My last point. You start with:
1
2
int main()
{

But later you have: if (carType == 1) {

It does not matter which style you use, but be consistent in its use. Have a look at
https://en.wikipedia.org/wiki/Indentation_style#Brace_placement_in_compound_statements
Personally I like the "Allman" style. Along with proper indenting and some blank lines it makes the code easier to read and follow. As a beginner and as a benefit to your-self make the code as easy to read as you can. This also helps to spot errors.

Andy
Wow Andy thank you very much for taking the time to answer my question! I appreciate it a lot! I did not know about the formatting thing so I changed it and I believe I fixed my indention problems. I'm trying to soak up all the tips and tricks along the way. My class is so fast paced that I get flustered trying to remember everything. I think that comes with TIME, so I just need to keep practicing. I will work on it some more to try to incorporate your suggestions! Thank you!
Thank you Thomas for your reply! very simple solution, I don't know why I was having such issues trying to come up with something!! I appreciate it!
Topic archived. No new replies allowed.