Need Looping Help Please

How can I do incorporate this in the current code I already wrote: If the user enters a negative number or a non-digit number, throw and handle an appropriate exception and prompt the user to enter another set of numbers.

#include<iostream>
using namespace std;

int main()
{
//Declare Variables
int lengthInFeet, lengthInInches; // Length in feet and Length Inches
double lengthInCentimeters;
const double FEET = 30.48;
const double INCHES = 2.54;


cout << '\t' << '\t' << "This program Converts Length given in Feet and Inches into Centimeters;" << endl << endl;

cout << '\t' << '\t' << " Enter the length in feet and inches respectively seperated by a space: ";
cin >> lengthInFeet >> lengthInInches;
cout << endl << endl;


//Calculations
lengthInCentimeters = lengthInFeet*FEET + lengthInInches*INCHES;

cout << '\t' << '\t' << lengthInFeet << " feet (foot) and " << lengthInInches << " inch(es) is equivalent to ";
std::cout << lengthInCentimeters << " centimeter(s) " << endl << endl;
}
What have you tried so far? I would factor out your user input into its own function. In your main, have a while loop and a try-catch.

Aside from practicing exceptions and looking up a tutorial on them, one tricky thing is that when you enter a non-digit, your cin (input) stream will go into a bad state, and you have to reset it. To reset the stream into a good state, you do something like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <limits>

// ...

int feet = -1;
int inches = -1;
while (true)
{
  if (!(cin >> feet >> inches) || feet < 0 || inches < 0)
  {
      // reset state of stream
      std::cin.clear();
      std::cin::ignore(std::numeric_limits<std::streamsize>::max(), '\n')
  }
  else
  {
       break;
  }
}

In your actual code, I would suggest asking and getting the input in its own function, and then throw from within that function.
Roughly the same. Plenty of scope to tidy up.
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
#include<iostream>

using namespace std;

int main()
{
    //Declare Variables
    int lengthInFeet{0}, lengthInInches{0}; // Length in feet and Length Inches
    double lengthInCentimeters;
    const double FEET = 30.48;
    const double INCHES = 2.54;

    bool doAgain{true};


    cout << '\t' << '\t' << "This program Converts Length given in Feet and Inches into Centimeters;" << endl << endl;

    while( doAgain == true)
    {
        try
        {
            cout << '\t' << '\t' << " Enter the length in feet and inches respectively seperated by a space: ";

            cin >> lengthInFeet >> lengthInInches;
            if( (lengthInFeet < 0) or (lengthInInches < 0) ) // EDIT
                throw(100);
            else
                doAgain = false;
        }

        catch(int error)
        {
            doAgain = true;
            cout << "Error: " << error << '\n';
            cin.clear();
            cin.ignore(1000, '\n');
        }
    }
    cout << endl << endl;


    //Calculations
    lengthInCentimeters = lengthInFeet*FEET + lengthInInches*INCHES;

    cout << '\t' << '\t' << lengthInFeet << " feet (foot) and " << lengthInInches << " inch(es) is equivalent to ";
    std::cout << lengthInCentimeters << " centimeter(s) " << endl << endl;
}


		This program Converts Length given in Feet and Inches into Centimeters;

		 Enter the length in feet and inches respectively seperated by a space: 2 cvf
Error: 100
		 Enter the length in feet and inches respectively seperated by a space: cvf 2
Error: 100
		 Enter the length in feet and inches respectively seperated by a space: -1 2
Error: 100
		 Enter the length in feet and inches respectively seperated by a space: 2 -1
Error: 100
		 Enter the length in feet and inches respectively seperated by a space: 2 1


		2 feet (foot) and 1 inch(es) is equivalent to 63.5 centimeter(s) 

Program ended with exit code: 0
Last edited on
Perhaps using exceptions:

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

int get(const char* prm)
{
	int a {};

	std::cin.exceptions(std::istream::badbit | std::istream::failbit);

	while (true) {
		try {
			std::cout << prm;
			std::cin >> a;
			if (a < 0)
				throw std::invalid_argument("Negative");
			break;
		}
		catch (const std::istream::failure&) {
			std::cout << "Not a number!\n";
			std::cin.clear();
			std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
		}
		catch (const std::invalid_argument&) {
			std::cout << "Invalid number (< 0)\n";
		}
		catch (...) {
			std::cout << "Unknown error!\n";
		}
	}

	std::cin.exceptions(0);

	return a;
}

int main()
{
	const double FEET {30.48};
	const double INCHES {2.54};

	std::cout << "This program converts Length given in Feet and Inches into Centimetres\n\n";
	std::cout << "Enter the length\n";

	const auto lengthInFeet {get("Whole feet: ")};
	const auto lengthInInches {get("Whole inches: ")};
	const auto lengthInCentimeters {lengthInFeet * FEET + lengthInInches * INCHES};

	std::cout << lengthInFeet << " feet (foot) and " << lengthInInches << " inch(es) is equivalent to ";
	std::cout << lengthInCentimeters << " centimetre(s)\n\n";
}

Last edited on
Thank you!!! I got the concept and it worked just fine.
std::ios_base::badbit is set in the stream's exception mask to indicate an error that's generally not recoverable.
https://eel.is/c++draft/ios.types#ios.iostate
Therefore it's an error to reset the state mask and try again forever.
Last edited on
Topic archived. No new replies allowed.