Trying to make it where it's invalid if a user enters a nonnumeric input and starts from the beginning

I tried to input it and I almost got it but I feel like there is on small change. At the end each time, the message asked me to input a number value no matter what and it starts in the beginning but each time at the end, valid or not, the user is prompted to put it again. What is a better way to write the code where the user has to start in the beginning and retry again if they enter a nonnumeric number?

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
  #include "stdafx.h"
/*
Name:Felice Reyes
Program name: Bookstore order
Program description: Order books from the book store that determines cost with taxes
Date: 06/15/2021
*/
#include<iostream>
#include<string>
#include<iomanip>
#include<vector>
#include<algorithm>
#include<conio.h>


using namespace std;


int main()
{
	here:
	char choice = 'Y';
	bool valid = true;

	    cout << fixed;
	    cout << setprecision(2);
		int height;
		string fname;
		cout << "\nPlease enter your first name: ";
		cin >> fname;
		string lname;
		cout << "\nPlease enter your last name: ";
		cin >> lname;
		cout << "\nHello " <<  fname << +" " << lname << "!";		
		cout << "\nPlease enter the height of the box: ";
		cin >> height;
		int weight;
		cout << "\nPlease enter the weight of the box: ";
		cin >> weight;
		float cost = 0;
		cout << "\nPlease input the cost of your book: ";
		cin >> cost;
		const float tax = .0825;
		float sale = 0;
		sale = (cost + (cost * tax));
		cout << "\nThe cost of your book is: $" << sale << endl;
		
		if (weight >= 10 && height >= 7)
		{
			cout << " \nThe box is too heavy and large";
		}
		
		else
		    if (height >= 7)
		{
			   cout << "\nThe box is too large";
			
		}
		else
		    if (weight >= 10)
		{
			    cout << "\nThe box is too heavy";
		}
		
			if (height <= 7 && height>0)
			{
				cout << "\nThe box height is OKAY";
			}
			if (weight <= 10 && weight>0)
			{
				cout << "\nThe box weight is OKAY";
			}			
		else
			if(weight<0)
				{
					cout << "\nInvalid input for weight";
				}
				
			if (height < 0)
					{
						cout << "\nInvalid input for height";
					}
			while (cout << "\nPlease enter a number: ")
			{
				int number;
				if (cin >> number) break;
				cin.clear();
				cin.ignore(1024, '\n');
				cout << "\nInvalid input, please try again\n";
				goto here;
			}

			system("cls");
			while (valid)
			{
				
		
			   cout << "\nWould you like to buy another book? (Y/N): " << endl;
			cin >> choice;
			if (choice == 'N' || choice == 'n')
			{
				cout << "Good bye! Enjoy your day, "<< fname << +" " << lname <<"!\n";
				break;
			}
			if (choice == 'Y' || choice == 'y')
			{
				goto here;
			}
			else if (choice != 'N' && choice != 'n' && choice != 'Y' && choice != 'y')
				cout << "Invalid input" << endl;
			valid = true;
		}
			
		system("pause");
		return 0;
	}
Line 83 is a mystery to any end-user. What is that line all about?

If you delete lines 83 to 91 inclusive it looks like you will get closer to the truth.

goto's are not good practice but lets put that to one side. You need to place line 21 here: in a sensible place unless you are deliberately asking for the buyers name for each book they buy and then put in a box.
Last edited on
Perhaps this:

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
#include <iostream>
#include <string>
#include <iomanip>
#include <string>
#include <limits>
#include <cstring>

template<typename T = int>
auto getNum(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 << "Not a number\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;
}

int main()
{
	const double tax {.0825};

	std::string fname, lname;

	std::cout << "\nPlease enter your first name: ";
	std::cin >> fname;

	std::cout << "Please enter your last name: ";
	std::cin >> lname;

	std::cout << "\nHello " << fname << " " << lname << "!\n";

	char choice {};

	do {
		double height {}, weight {}, cost {};

		do {
			height = getNum("Please enter the height of the book (1 - 7): ");
		} while ((height < 1 || height > 7) && (std::cout << "Invalid book height\n"));

		do {
			weight = getNum("Please enter the weight of the book (1 - 10): ");
		} while ((weight < 1 || weight > 10) && (std::cout << "Invalid book weight\n"));

		do {
			cost = getNum<double>("\nPlease input the price of the book: ");
		} while (cost < 0 && (std::cout << "Invalid cost\n"));

		std::cout << "\nThe cost of your book is: $" << std::fixed << std::setprecision(2) << cost + (cost * tax) << '\n';

		do {
			std::cout << "\nWould you like to buy another book? (Y/N): ";
			std::cin >> choice;

			choice = static_cast<char>(std::toupper(static_cast<unsigned char>(choice)));
		} while (choice != 'N' && choice != 'Y' && (std::cout << "Invalid input\n"));
	} while (choice == 'Y');

	std::cout << "Good bye! Enjoy your day, " << fname << " " << lname << "!\n";
}

Hello digitalFun157,

I take a different approach with your program and 1 of the 1st things I noticed is:

Please enter your first name: Etienne
Please enter your last  name: Navarre

Hello Etienne Navarre!

Please enter the height of the box:  // Height in what? Inches, feet cm or meters?

Please enter the weight of the box:  // Same thing weight in what?


The questions here may not make any difference, but it is nice to know what you are working with.

I also noticed that you need a 3rd variable for length. To have a box that is OK at 3 inches high may be good for the program, but what is the length is 5 feet long? Not good.

I did notice that the if statements do nor work properly. I have not worked on that yet because I have another question: given these variables constexpr int MAXHEIGHT{}, MAXLENGTH{}, MAXWEIGHT{}; what numbers should be inside the {}s? Once I know that I can better understand the if statements.

This bit of code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
while (cout << "\n Please enter a number: ")  // <--- This has no purpose.
{
    int number;

    cin >> number;

    if (!cin)
    {
        cout << "\n     Invalid input, please try again\n";
                
        cin.clear();
        cin.ignore(1024, '\n');
    }
    else
    {
        break;
    }

    /*goto here;*/
}

First the variable "number" is defined inside the while loop. The problem when the while loop is finished and the closing } is reached the variable is destroyed. Also you never make use of this variable.

To make the while loop work you need the "else" part.

What would be better and you have a good start on it is:
1
2
3
4
5
6
7
8
9
int number{};

while (cout << "\n Please enter a number: " && !(std::cin >> number))
{
    cout << "\n     Invalid input, please try again\n";

    cin.clear();
    cin.ignore(1024, '\n');
}

Here the lhs of && is very likely to be true all the time. I do not know of any way to make the "cout" statement fail. the rhs of && is the more important part. In the end though it is still a useless bit of code. Removing it makes no difference.

At the beginning of the file you include "<conio.h>". This is not a standard C++ header file and some compilers do not have this file available to use. And what is available is a mere shadow of what it use to be.

Andy
Topic archived. No new replies allowed.