Variable may be uninitialized/is used uninitialized - c++

I'm writing an English-Metric converter program in C++, and I'm trying to use try, throw, catch to reject negative/non-numeric values in the 'main' function.
My two problems are:
1.)
Whenever I enter, say, 'g' into the console, I get an output: 0 inches is equal to 0 centimeters AND THEN I get the error display that I want to pop up. What i need is only the error display to be output.
2.) When I enter a negative number, like -3, I get the proper conversion as a negative number when I would like it to tell me my input is invalid.
Here is my code.
#include <iostream>
#include <cctype>
char menuSelect();
using namespace std;
int main(int argc, const char * argv[])
{
double inches;
double centimeters;
char select;
try
{
do
{
if (centimeters < 0.0 || inches < 0.0)
throw 0;
if (!cin)
throw 0;
select = menuSelect();
if (select == 'E')
{
cout << "Enter the number of inches: ";
cin >> inches;
centimeters = inches * 2.54;
cout << inches << " inches is equal to " << centimeters
<< " centimeters." << endl;
}
else if (select == 'M')
{
cout << "Enter the number of centimeters: ";
cin >> centimeters;
inches = centimeters / 2.54;
cout << centimeters << " Centimeters is equal to " << inches
<< " inches." << endl;
}
} while (select != 'Q');
}
catch (int errID)
{
cout << "Error: " << errID << endl;
cout << "Please enter a positive number. ";
}
return 0;
}

It should be something like that: (I added a flag bool bNeg = false, if (inches>=0) and if (centimeters>=0) just after the input & if the input is negative for either 'E' or 'M' set bNeg = true)
bool bNeg = false;
if (select == 'E')
{
cout << "Enter the number of inches: ";
cin >> inches;
if (inches>=0) { // No meaning to negative values
centimeters = inches * 2.54;
cout << inches << " inches is equal to " << centimeters
<< " centimeters." << endl;
}
else bNeg = true;
}
else if (select == 'M')
{
cout << "Enter the number of centimeters: ";
cin >> centimeters;
if (centimeters>=0) { // No meaning to negative values
inches = centimeters / 2.54;
cout << centimeters << " Centimeters is equal to " << inches
<< " inches." << endl;
}
else bNeg = true;
}
if (bNeg) {
// tbd: say what you want to say
}

Related

Is there any way to run a program with a void function prototype within another void function prototype?

This question originates from a problem I am attempting to solve for an "Introduction to Structured Programming" C++ class.
The problem statement is as follows:
The program asks the user if he or she wants to convert from feet and inches to meters and centimeters or from meters and centimeters to feet and inches. the program then performs the desired conversion. have the user respond by typing the integer 1 for one type of conversion and 2 for the other conversion. The program reads the user's answer and then executes and if-else statement. Each brand of the if-else statement will be a function call. the 2 functions called in the if-else statement will have function definitions that are very similar to the programs for the previous 2 Practice Programs. Thus, they will be function definitions that call other functions in their function bodies. include a loop that lets the user repeat this computation for new input values until the user says he or she wants to end the program.
For the "previous 2 Practice Programs," I already solved them wholly by using void function prototypes. The first program was to convert feet and inches into meters and centimeters. The second program was to convert meters back into feet and inches.
When I run my attempt to the question above in Visual Studio, the compiler suggests an expected ";" after the first void input(int& feet, double& inches, double& meters, double& centimeters) and the other void input within void ConvertToEnglish(). Even when I input the semicolons, the variables within those void scopes are now unknown.
#include <iostream>
#include <cmath>
using namespace std;
void input(int& feet, double& inches, double& meters, double& centimeters);//Needed function prototype for inputs
//Declared reference values:
//Feet as reference int and inches, meters, centimeters as reference doubles
//Declarations carried out through each prototype
void conversion(int& feet, double& inches, double& meters, double& centimeters);//Needed function prototype for conversion calc
void output(int& feet, double& inches, double& meters, double& centimeters);//Needed function prototype for outputs
void ConvertToMetric();
void ConvertToEnglish();
int main()
{
char ans; //loop control variable
int which; //stores the choice of conversion
do
{
//Add a loop here to ensure that the user enters either 1 or 2
cout << "\nEnter 1 for English to Metric or " << endl
<< "Enter 2 for Metric to English conversion"
<< endl;
cin >> which;
if (1 == which)
ConvertToMetric();//calls the ConvertToMetric functions
else
ConvertToEnglish();//calss the ConvertToEnglish functions
cout << "Y or y allows another choice of conversion. "
<< "any other quits" << endl;
cin >> ans;
} while ('y' == ans || 'Y' == ans);
return 0;
}
void ConvertToMetric()
{
void input(int& feet, double& inches, double& meters, double& centimeters)//Function prototype for user inputs
{
cout << "Enter feet as an integer: ";
cin >> feet;//User inputs feet as integer
cout << "Enter inches as double: ";
cin >> inches;//User inputs inches as double
if (feet < 0 || inches < 0)//If statement when either feet or inches is equal to zero or negative
{
cout << endl;
cout << "Invalid data - please re-enter\n"
<< endl;//Required output for invalid input
cout << "Enter feet as an integer: ";//User goes through process again
cin >> feet;
cout << "Enter inches as double: ";
cin >> inches;
}
}
void conversion(int& feet, double& inches, double& meters, double& centimeters)//Function prototype for imperial to metric conversions
{
meters = feet * 0.3048;//Converts inputted feet to meters
centimeters = (inches / 12) * 0.3048;//Converts inputted inches to feet then to meters
meters += centimeters;//Adds both calculated values together to get total meters
}
void output(int& feet, double& inches, double& meters, double& centimeters)//Function prototype for value outputs
{
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);//Decimal precision to two the hundreths place
cout << meters << " meters corresponds to " << feet << " feet, " << inches << " inches\n";//Required output for all values
cout << endl;
}
}
void ConvertToEnglish()
{
void input(int& feet, double& inches, double& meters, double& centimeters)//Function prototype for user inputs
{
cout << "Enter a number of meters as a double\n";
cin >> meters;//User inputs meters as double
if (meters < 0)//If statement when either meters is equal to zero or negative
{
cout << endl;
cout << "Invalid data - please re-enter\n"
<< endl;//Required output for invalid input
cout << "Enter a number of meters as a double\n";//User goes through process again
cin >> meters;
}
}
void conversion(int& feet, double& inches, double& meters, double& centimeters)//Function prototype for imperial to metric conversions
{
double feetDec = meters / 0.3048;//To get double num
feet = meters / 0.3048;//True value of inputted meters converted into feet
int feetInt = floor(meters / 0.3048);//To get integer num
inches = (feetDec - feetInt) * 12;//Calc for decimal part of num converted into inches
}
void output(int& feet, double& inches, double& meters, double& centimeters)//Function prototype for value outputs
{
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);//Decimal precision to two the hundreths place
cout << meters << " meters corresponds to " << feet << " feet, " << inches << " inches\n";//Required output for all values
cout << endl;
}
}
This code inside of ConvertToMetric() and ConvertToEnglish() is all wrong. You can't implement nested functions inside of functions like you are trying to do (well, you can, using lambdas, but that is a whole other subject, and is not what this assignment is asking for).
You have forward-declared the inner functions above main(), which is fine (but unnecessary, since main() does not call them). You just need to move their implementations out to file scope, and then call them from inside of ConvertToMetric() and ConvertToEnglish(), like this:
#include <iostream>
#include <limits>
#include <cmath>
#include <iomanip>
using namespace std;
void ConvertToMetric();
void ConvertToEnglish();
int main()
{
char ans;
int which;
do
{
cout << "\nEnter 1 for English to Metric or " << endl
<< "Enter 2 for Metric to English"
<< endl;
cin >> which;
if (1 == which)
ConvertToMetric();
else if (2 == which)
ConvertToEnglish();
else {
cout << endl;
cout << "Invalid data\n" << endl;
}
cout << "Y or y allows another choice of conversion. Any other quits" << endl;
cin >> ans;
} while ('y' == ans || 'Y' == ans);
return 0;
}
void inputEnglish(int& feet, double& inches)
{
do {
cout << "Enter feet as an integer: ";
if (cin >> feet) {
if (feet >= 0)
break;
}
else {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
cout << endl;
cout << "Invalid data - please re-enter\n" << endl;
} while (true);
do {
cout << "Enter inches as double: ";
if (cin >> inches) {
if (inches >= 0)
break;
}
else {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
cout << endl;
cout << "Invalid data - please re-enter\n" << endl;
} while (true);
}
void conversionEnglishToMetric(int feet, double inches, double& meters, double& centimeters)
{
meters = feet * 0.3048;
centimeters = (inches / 12) * 0.3048;
meters += centimeters;
}
void outputMetric(int feet, double inches, double meters, double centimeters)
{
cout << fixed << showpoint << setprecision(2);
cout << feet << " feet, " << inches << " inches corresponds to " << meters << " meters, " << centimeters << " centimeters\n";
cout << endl;
}
void ConvertToMetric()
{
int feet;
double inches, meters, centimeters;
inputEnglish(feet, inches);
conversionEnglishToMetric(feet, inches, meters, centimeters);
outputMetric(feet, inches, meters, centimeters);
}
void inputMetric(double& meters, double& centimeters)
{
do {
cout << "Enter a number of meters as a double\n";
if (cin >> meters) {
if (meters >= 0)
break;
}
else {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
cout << endl;
cout << "Invalid data - please re-enter\n" << endl;
} while (true);
do {
cout << "Enter a number of centimeters as a double\n";
if (cin >> centimeters) {
if (centimeters >= 0)
break;
}
else {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
cout << endl;
cout << "Invalid data - please re-enter\n" << endl;
} while (true);
}
void conversionMetricToEnglish(double meters, double centimeters, int& feet, double& inches)
{
// TODO: fix this to take centimeters into account correctly!
double feetDec = meters / 0.3048;
feet = meters / 0.3048;
int feetInt = floor(meters / 0.3048);
inches = (feetDec - feetInt) * 12;
}
void outputEnglish(double meters, double centimeters, int feet, double inches)
{
cout << fixed << showpoint << setprecision(2);
cout << meters << " meters, " << centimeters << " centimeters corresponds to " << feet << " feet, " << inches << " inches\n";
cout << endl;
}
void ConvertToEnglish()
{
int feet;
double inches, meters, centimeters;
inputMetric(meters, centimeters);
conversionMetricToEnglish(meters, centimeters, feet, inches);
outputEnglish(meters, centimeters, feet, inches);
}
Alternatively, using lambdas instead:
#include <iostream>
#include <cmath>
using namespace std;
void ConvertToMetric();
void ConvertToEnglish();
int main()
{
char ans; //loop control variable
int which; //stores the choice of conversion
do
{
//Add a loop here to ensure that the user enters either 1 or 2
cout << "\nEnter 1 for English to Metric or " << endl
<< "Enter 2 for Metric to English conversion"
<< endl;
cin >> which;
if (1 == which)
ConvertToMetric();//calls the ConvertToMetric functions
else if (2 == which)
ConvertToEnglish();//calss the ConvertToEnglish functions
else {
cout << endl;
cout << "Invalid data\n" << endl;
}
cout << "Y or y allows another choice of conversion. "
<< "any other quits" << endl;
cin >> ans;
} while ('y' == ans || 'Y' == ans);
return 0;
}
void ConvertToMetric()
{
int feet;
double inches, meters, centimeters;
auto input = [&]() {
do {
cout << "Enter feet as an integer: ";
if (cin >> feet) {
if (feet >= 0)
break;
}
else {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
cout << endl;
cout << "Invalid data - please re-enter\n" << endl;
} while (true);
do {
cout << "Enter inches as double: ";
if (cin >> inches) {
if (inches >= 0)
break;
}
else {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
cout << endl;
cout << "Invalid data - please re-enter\n" << endl;
} while (true);
};
auto conversion = [&]() {
meters = feet * 0.3048;
centimeters = (inches / 12) * 0.3048;
meters += centimeters;
};
auto output = [&]() {
cout << fixed << showpoint << setprecision(2);
cout << feet << " feet, " << inches << " inches corresponds to " << meters << " meters, " << centimeters << " centimeters\n";
cout << endl;
};
input();
conversion();
output();
}
void ConvertToEnglish()
{
auto input = [&]() {
do {
cout << "Enter a number of meters as a double\n";
if (cin >> meters) {
if (meters >= 0)
break;
}
else {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
cout << endl;
cout << "Invalid data - please re-enter\n" << endl;
} while (true);
do {
cout << "Enter a number of centimeters as a double\n";
if (cin >> centimeters) {
if (centimeters >= 0)
break;
}
else {
cin.clear();
cin .ignore(numeric_limits<streamsize>::max(), '\n');
}
cout << endl;
cout << "Invalid data - please re-enter\n" << endl;
} while (true);
};
auto conversion = [&]() {
// TODO: fix this to take centimeters into account correctly!
double feetDec = meters / 0.3048;
feet = meters / 0.3048;
int feetInt = floor(meters / 0.3048);
inches = (feetDec - feetInt) * 12;
};
auto output = [&]() {
cout << fixed << showpoint << setprecision(2);
cout << meters << " meters, " << centimeters << " centimeters corresponds to " << feet << " feet, " << inches << " inches\n";
cout << endl;
};
input();
conversion();
output();
}

Part of my code was skipped as part of my if statment

So im trying to make a calculator and i added a part so i can calculate area, first i asked for integer or geometry math, when i choose geometry, it skips my question of you want to calculate volume. But there were no compiler errors. It everything after " else if (choice == "geometry") {" and until the last line. Anyone knows how to fix.
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
int main()
{
string choice;
cout << "choose integer or geometry\n";
cin >> choice;
if (choice == "integer") {
double num1{ 0 };
double num2{ 0 };
cout << "pick a number\n";
cin >> num1;
cout << "pick another number\n";
cin >> num2;
string integerChoice;
cout << "choose addition, subtraction, multipliction, or division\n";
cin >> integerChoice;
if (integerChoice == "addition") {
cout << num1 << " + " << num2 << " is " << num1 + num2
<< '\n';
}
else if (integerChoice == "subtraction") {
cout << num1 << " - " << num2 << " is " << num1 - num2
<< '\n';
}
else if (integerChoice == "multiplication") {
cout << num1 << " * " << num2 << " is " << num1 * num2
<< '\n';
}
else if (integerChoice == "division") {
cout << num1 << " / " << num2 << " is " << num1 / num2
<< '\n';
}//integer is done
}
else if (choice == "geometry") {
string geoChoice1;
cout << "do you want to calculate volume, enter yes or no\n";
cin >> geoChoice1;
if (geoChoice1 == "yes") {
cout << "choose retangular prism(incudes cubes), cone, or cylinder\n";
string volumeChoice;
cin >> volumeChoice;
if (volumeChoice == "rectangular prism") {
double recPrismLength{ 0 };
double recPrismWidth{ 0 };
double recPrismHeight{ 0 };
cout << "Enter the length\n";
cin >> recPrismLength;
cout << "Enter the width\n";
cin >> recPrismWidth;
cout << "Enter the height\n";
cin >> recPrismHeight;
cout << recPrismLength << " * " << recPrismWidth << " * " << recPrismHeight << " is " <<
recPrismLength * recPrismWidth * recPrismHeight << '\n';
}
else if (volumeChoice == "cylinder") {
float cHeight;
float cRadius;
const double pi{ 3.14159265358979323846 };
float cFormula{ pi * pow(2.0, cRadius) * cHeight };
cout << "Enter the height of the cylinder\n";
cin >> cHeight;
cout << "Enter the radius of the cylinder\n";
cin >> cRadius;
cout << cFormula;
}
else if (geoChoice1 == "no") {
Fixed Code:
#include <iostream>
#include <string>
#include <cmath>
#include <algorithm>
using namespace std;
std::string ToLower(std::string str) {
std::transform(str.begin(), str.end(), str.begin(),
[](unsigned char c) { return std::tolower(c); });
}
int main()
{
string choice;
cout << "choose integer or geometry\n";
cin >> choice;
if (choice == "integer") {
double num1{ 0 };
double num2{ 0 };
cout << "pick a number\n";
cin >> num1;
cout << "pick another number\n";
cin >> num2;
string integerChoice;
cout << "choose addition, subtraction, multipliction, or division\n";
cin >> integerChoice;
if (integerChoice == "addition") {
cout << num1 << " + " << num2 << " is " << num1 + num2
<< '\n';
}
else if (integerChoice == "subtraction") {
cout << num1 << " - " << num2 << " is " << num1 - num2
<< '\n';
}
else if (integerChoice == "multiplication") {
cout << num1 << " * " << num2 << " is " << num1 * num2
<< '\n';
}
else if (integerChoice == "division") {
cout << num1 << " / " << num2 << " is " << num1 / num2
<< '\n';
}//integer is done
}
else if (choice == "geometry") {
string geoChoice1;
while (!(geoChoice1 == "yes" || geoChoice1 == "no"))
cout << "do you want to calculate volume, enter yes or no\n";
cin >> geoChoice1;
ToLower(geoChoice1);
if (geoChoice1 == "yes") {
cout << "choose retangular prism(incudes cubes), cone, or cylinder\n";
string volumeChoice;
cin >> volumeChoice;
ToLower(volumeChoice);
if (volumeChoice == "rectangular prism") { //this will never be executed, as the >> operator skips whitespace, and therefore will only read "rectangular"
//I will leave this for you to fix
double recPrismLength{ 0 };
double recPrismWidth{ 0 };
double recPrismHeight{ 0 };
cout << "Enter the length\n";
cin >> recPrismLength;
cout << "Enter the width\n";
cin >> recPrismWidth;
cout << "Enter the height\n";
cin >> recPrismHeight;
cout << recPrismLength << " * " << recPrismWidth << " * " << recPrismHeight << " is " <<
recPrismLength * recPrismWidth * recPrismHeight << '\n';
}
else if (volumeChoice == "cylinder") {
float cHeight;
float cRadius;
const double pi{ 3.14159265358979323846 };
double cFormula{ pi * pow(2.0, cRadius) * cHeight }; //this will always be the same, please note, because cHeight and cRadius are only filled after this function
cout << "Enter the height of the cylinder\n";
cin >> cHeight;
cout << "Enter the radius of the cylinder\n";
cin >> cRadius;
cout << cFormula;
break;
}
}
else if (geoChoice1 == "no") break;
else cout << "Please enter something I understand, either 'yes' or 'no'.\n";
} //this was missing
} //this was missing
Your code did not take into account if the user inputted "Yes" with a capital Y. The code would just conclude that "Yes" would not be equal to "yes". I made a function which converts your input into a lowercase form, then evaluates it, and if it is not "yes" or "no" asks the user to put it again.
There are some other errors which I have put comments on, that you will have to fix.

Creating a function to output a string when the input is negative or zero. First time doing user-defined functions

I am trying to create a user-define function in C++ to prevent an endless loop from inputting an incorrect input for a double variable and check if an input is negative or zero. If that's the case the function will go into a do-while loop to ask the user to try again until the value is no longer something other than a double, negative, or zero.
The function fix() is the the user-defined
#include <iostream>
#include <string>
#include <iomanip>
#include <cmath>
using namespace std;
string fix(double x)
{
string B_error = "B cannot be zero or negative. Please try again: ";
string H_error = "H cannot be zero or negative. Please try again: ";
string h_error = "b cannot be zero or negative. Please try again: ";
string b_error = "h cannot be zero or negative. Please try again: ";
string r_error = "r cannot be zero or negative. Please try again: ";
string y_error;
while (!(cin >> x))
{
if (cin.fail())
{
cout << "Erroneous input. Please try again:\n";
cin.clear(); // used to prevent an endless loop if an input type is not an integer
cin.ignore(10000, '\n');
}
}
if (x == 'B')
{
y_error = B_error;
if (x <= 0)
{
do
{
return y_error;
cin >> x;
}
while (x <= 0);
}
}
return 0;
}
int main()
{
int selection;
double I, B, H, b, h, r, fix(double);
cout << "Please select the type of beam:\n"
<< "1) I-Beam\n"
<< "2) Rectangular Beam\n"
<< "3) Cylindrical Beam\n";
while (!(cin >> selection) || selection < 1 || selection > 3)
{
if (cin.fail() || selection < 1 || selection > 3)
{
cout << "Erroneous input. Please try again:\n";
cin.clear(); // used to prevent an endless loop if an input type is not an integer
cin.ignore(10000, '\n');
}
}
switch (selection)
{
case 1:
cout << "You have selected I-beam. All inputs must be in inches.\n"
<< "Please input the value for B: ";
fix(B);
cout << "Please input the value for H: ";
fix(H);
if (H <= 0)
{
do
{
cout << "H cannot be zero or negative. Please try again: ";
cin >> H;
}
while (H <= 0);
}
cout << "Please input the value for b: ";
fix(b);
if (b <= 0)
{
do
{
cout << "b cannot be zero or negative. Please try again: ";
cin >> b;
}
while (b <= 0);
}
else if (b > B)
{
do
{
cout << "b cannot be larger than B. Please try again: ";
cin >> b;
}
while (b > B);
}
cout << "Please input the value for h: ";
fix(h);
if (h <= 0)
{
do
{
cout << "h cannot be zero or negative. Please try again: ";
cin >> h;
}
while (h <= 0);
}
else if (h > H)
{
do
{
cout << "h cannot be larger than H. Please try again: ";
cin >> H;
}
while (h > H);
}
I = (B*H*H*H - b*h*h*h)/12.;
cout << "\nResults for an I-beam with B = " << B
<< ", H = " << H << ", b = " << b << ", and h = " << h << endl;
cout << setfill('-') << setw(32) << "" << endl;
break;
case 2:
cout << "You have selected rectangular beam. All inputs must be in inches.\n"
<< "Please input the value for b: ";
fix(b);
if (b <= 0)
{
do
{
cout << "b cannot be zero or negative. Please try again: ";
cin >> b;
}
while (b <= 0);
}
cout << "Please input the value for h: ";
fix(h);
if (h <= 0)
{
do
{
cout << "h cannot be zero or negative. Please try again: ";
cin >> h;
}
while (h <= 0);
}
I = b*h*h*h/12.;
cout << "\nResults for a rectangular beam with b = " << b << " and h = " << h << endl;
cout << setfill('-') << setw(32) << "" << endl;
break;
case 3:
cout << "You have selected cylindrical beam. All inputs must be in inches.\n"
<< "Please input the value of r: ";
fix(r);
if (r <= 0)
{
do
{
cout << "r cannot be zero or negative. Please try again: ";
cin >> r;
}
while (r <= 0);
}
I = M_PI*pow(r,4)/4.;
cout << "\nResults for a cylindrical beam with r = " << r << endl;
cout << setfill('-') << setw(32) << "" << endl;
break;
}
cout << "The value of the moment of inertia for this beam is: " << I << "in^4" << "\n\n";
return 0;
}
I removed the issues. You are confusing instances of classes with functions. Functions don't have to be initialized, instances have to if they are outside of the class.
I wrote some comments along the code. It is still not beautiful but at least it works.
string FUNCTION(double) btw. means the function only can or should return a "string". If you are returning nothing the function is written like so void FUNCTION(double).
If your return f.e. a string you have to write something that is receiving the returned string like so:
#include <iostream>
/*
std::string returning_value;
returning_value = FUNCTION(1.0);
*/
//or
std::string FUNCTION(double function_a); //prototype of the function
//you need this if you write the function underneath the main() function
//The main function is returning "return 0" so since "0" is an "int"
//meaning main is always "int main()" btw. because it is a function,
//just not some function but the "main function" thats called by the OS
int main()
{
std::string returning_value;
double a = 0.1; //initializing with 0.1
returning_value = FUNCTION(a);
std::cout << returning_value << std::endl;
//and in both cases the function would look like:
return 0;
}
std::string FUNCTION(double function_a)
{
std::string returning_value_a = "This is a string that will be returned";
if(function_a == 0.1)
{
returning_value_a = "This is another string";
}
return returning_value_a;
}
Your code with the least amount fixed that you got it at least working
and you can test with how to get the right output you want to get. Have fun :) Hope my answer helps you :)
#include <iostream>
#include <string>
#include <iomanip>
#include <cmath>
using namespace std;
void fix(double x)
{
string B_error = "B cannot be zero or negative. Please try again: ";
string H_error = "H cannot be zero or negative. Please try again: ";
string h_error = "b cannot be zero or negative. Please try again: ";
string b_error = "h cannot be zero or negative. Please try again: ";
string r_error = "r cannot be zero or negative. Please try again: ";
string y_error;
while (!(cin >> x))
{
if (cin.fail())
{
cout << "Erroneous input. Please try again:\n";
cin.clear(); // used to prevent an endless loop if an input type is not an integer
cin.ignore(10000, '\n');
}
}
//warning: comparing floating point with == or != is unsafe
if (x == 'B')
{
y_error = B_error;
if (x <= 0)
{
do
{
cin >> x;
}
while (x <= 0);
}
}
}
int main()
{
int selection;
double I, B, H, b, h, r;
//You need to initialize the variables with a value
I = 1.0;
B = 1.0;
H = 1.0;
b = 1.0;
h = 1.0;
r = 1.0;
//functions don't need to be initialized, thats for Instanzes of classes
//double fix(double);
cout << "Please select the type of beam:\n"
<< "1) I-Beam\n"
<< "2) Rectangular Beam\n"
<< "3) Cylindrical Beam\n";
while (!(cin >> selection) || selection < 1 || selection > 3)
{
if (cin.fail() || selection < 1 || selection > 3)
{
cout << "Erroneous input. Please try again:\n";
cin.clear(); // used to prevent an endless loop if an input type is not an integer
cin.ignore(10000, '\n');
}
}
switch (selection)
{
case 1:
cout << "You have selected I-beam. All inputs must be in inches.\n"
<< "Please input the value for B: ";
fix(B);
cout << "Please input the value for H: ";
fix(H);
if (H <= 0)
{
do
{
cout << "H cannot be zero or negative. Please try again: ";
cin >> H;
}
while (H <= 0);
}
cout << "Please input the value for b: ";
fix(b);
if (b <= 0)
{
do
{
cout << "b cannot be zero or negative. Please try again: ";
cin >> b;
}
while (b <= 0);
}
else if (b > B)
{
do
{
cout << "b cannot be larger than B. Please try again: ";
cin >> b;
}
while (b > B);
}
cout << "Please input the value for h: ";
fix(h);
if (h <= 0)
{
do
{
cout << "h cannot be zero or negative. Please try again: ";
cin >> h;
}
while (h <= 0);
}
else if (h > H)
{
do
{
cout << "h cannot be larger than H. Please try again: ";
cin >> H;
}
while (h > H);
}
I = (B*H*H*H - b*h*h*h)/12.;
cout << "\nResults for an I-beam with B = " << B
<< ", H = " << H << ", b = " << b << ", and h = " << h << endl;
cout << setfill('-') << setw(32) << "" << endl;
break;
case 2:
cout << "You have selected rectangular beam. All inputs must be in inches.\n"
<< "Please input the value for b: ";
fix(b);
if (b <= 0)
{
do
{
cout << "b cannot be zero or negative. Please try again: ";
cin >> b;
}
while (b <= 0);
}
cout << "Please input the value for h: ";
fix(h);
if (h <= 0)
{
do
{
cout << "h cannot be zero or negative. Please try again: ";
cin >> h;
}
while (h <= 0);
}
I = b*h*h*h/12.;
cout << "\nResults for a rectangular beam with b = " << b << " and h = " << h << endl;
cout << setfill('-') << setw(32) << "" << endl;
break;
case 3:
cout << "You have selected cylindrical beam. All inputs must be in inches.\n"
<< "Please input the value of r: ";
fix(r);
if (r <= 0)
{
do
{
cout << "r cannot be zero or negative. Please try again: ";
cin >> r;
}
while (r <= 0);
}
I = M_PI*pow(r,4)/4.;
cout << "\nResults for a cylindrical beam with r = " << r << endl;
cout << setfill('-') << setw(32) << "" << endl;
break;
}
cout << "The value of the moment of inertia for this beam is: " << I << "in^4" << "\n\n";
return 0;
}
So, I had to add another function to check if B < b and H < h and add a do-while loop after the while loop in the fix function.
Here's my code with the fix:
#include <iostream>
#include <string>
#include <iomanip>
#include <cmath>
using namespace std;
void fix(double &x)
{
while (!(cin >> x))
{
if (cin.fail())
{
cout << "Erroneous input. Please try again:\n";
cin.clear(); // used to prevent an endless loop if an input type is not a double
cin.ignore(10000, '\n');
}
}
string return_x = "This cannot be zero or negative. Please try again: ";
while (x <= 0)
{
cout << return_x << endl;
cin >> x;
}
}
void fix2(double &x, double &y)
{
while (x < y)
{
cout << x << " cannot be less than " << y << endl;
fix(y);
}
}
int main()
{
int selection;
double I = 1.0;
double B = 1.0;
double H = 1.0;
double b = 1.0;
double h = 1.0;
double r = 1.0;
cout << "Please select the type of beam:\n"
<< "1) I-Beam\n"
<< "2) Rectangular Beam\n"
<< "3) Cylindrical Beam\n";
while (!(cin >> selection) || selection < 1 || selection > 3)
{
if (cin.fail() || selection < 1 || selection > 3)
{
cout << "Erroneous input. Please try again:\n";
cin.clear(); // used to prevent an endless loop if an input type is not an integer
cin.ignore(10000, '\n');
}
}
switch (selection)
{
case 1:
cout << "You have selected I-beam. All inputs must be in inches.\n"
<< "Please input the value for B: ";
fix(B);
cout << "Please input the value for H: ";
fix(H);
cout << "Please input the value for b: ";
fix(b);
fix2(B, b);
cout << "Please input the value for h: ";
fix(h);
fix2(H, h);
I = (B * H * H * H - b * h * h * h) / 12.;
cout << "\nResults for an I-beam with B = " << B << ", H = " << H
<< ", b = " << b << ", and h = " << h << endl;
cout << setfill('-') << setw(32) << "" << endl;
break;
case 2:
cout << "You have selected rectangular beam. All inputs must be in inches.\n"
<< "Please input the value for b: ";
fix(b);
cout << "Please input the value for h: ";
fix(h);
I = b * h * h * h / 12.;
cout << "\nResults for a rectangular beam with b = " << b
<< " and h = " << h << endl;
cout << setfill('-') << setw(32) << "" << endl;
break;
case 3:
cout << "You have selected cylindrical beam. All inputs must be in inches.\n"
<< "Please input the value of r: ";
fix(r);
I = M_PI * pow(r, 4) / 4.;
cout << "\nResults for a cylindrical beam with r = " << r << endl;
cout << setfill('-') << setw(32) << "" << endl;
break;
}
cout << "The value of the moment of inertia for this beam is: " << I
<< "in^4" << "\n\n";
return 0;
}

How to loop but reject non-numerical inputs?

How do I make a function that will terminate the program if the user says e, and loop if the user presses l at any time?
How do I make the program reask the user for number input if the user inputs letters instead of numbers? Currently, the program terminates when I input blah, for instance. My obstacle is the bool die definition: I'm not sure how to use bool die to loop instead of die (my teacher required bool die usage.)
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
bool die(const string & msg);
int main() {
// declaring variables:
unsigned QUARTERS;
unsigned DIMES;
unsigned NICKELS;
unsigned PENNIES;
double total;
cout << "********************************************************" << endl;
cout << " Welcome to Crazy Coin Counter! " << endl;
cout << "********************************************************" << endl << endl;
// user input:
//QUARTERS
do {
cout << " # QUARTERS: ";
cin >> QUARTERS;
if (cin){
if (QUARTERS < 1000)
cout << " --> Input Successful!" << endl;
}
else die(" --> :( Input Unsuccessful!");
cout << " You must put in less than 1000 quarters! Please try again." << endl << endl << endl;
} while (QUARTERS >= 1000 );
//DIMES
do{
cout << endl << " # DIMES: ";
cin >> DIMES;
if (cin){
if (DIMES < 1000)
cout << " --> Input Successful!" << endl;
}
else die(" --> :( Input Unsuccessful!");
if (DIMES >= 1000)
cout << " You must put in less than 1000 dimes! Please try again." << endl << endl << endl;
} while (DIMES >= 1000);
//NICKELS
do {
cout << endl << " # NICKLES: ";
cin >> NICKELS;
if (cin){
if (NICKELS < 1000)
cout << " --> Input Successful!" << endl;
}
else die(" --> :( Input Unsuccessful!");
if (NICKELS >= 1000)
cout << " You must put in less than 1000 nickels! Please try again." << endl << endl << endl;
} while (NICKELS >= 1000);
//PENNIES
do {
cout << endl << " # PENNIES: ";
cin >> PENNIES;
if (cin){
if (PENNIES < 1000)
cout << " --> Input Successful!" << endl;
}
else die(" --> :( Input Unsuccessful!");
if (PENNIES >= 1000)
cout << " You must put in less than 1000 pennies! Please try again." << endl;
} while (PENNIES >= 1000);
// calculations:
total = (QUARTERS * 0.25) + (DIMES * 0.1) + (NICKELS * 0.05) + (PENNIES * 0.01);
// output:
cout << endl <<endl<< "Congrats! You have $" << total << " worth of coins! " << endl << endl << endl;
}
// function definition
bool die(const string & msg){
cout << " " << msg << endl;
exit(EXIT_FAILURE);
}
Try something like this:
while ( true ) // Loop forever
{
cout << "Enter 'e' to exit:";
std::string answer;
getline(cin, answer);
if (answer == "e")
{
break; // Break out of the loop
}
else
{
cout << "\nWrong answer.\n";
continue; // The continue would start at the top of the loop.
}
}
There are many other techniques that you can find by searching StackOverflow for "c++ terminate loop".
Edit 1: Checking numerical input
The simplest method for checking numerical input is to test the result of inputting the number:
unsigned int quarters; // Using unsigned because quantities can't be negative.
cout << "Enter number of quarters: ";
if (cin >> quarters) // Input and test in same statement.
{
cout << "Your total is " << (quarters * 0.25) << "\n";
}
else
{
// Handle incorrect input
cout << "Invalid input, try again.\n";
}

Why do my stream input operations get skipped over?

I have this code where in option lists will display when run. my problem is when I enter number 2, the option 2 program doesn't work well. It just go directly to asking the amount paid instead of asking first the cost of purchase.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
float circle (float a)
{
float z;
z = 3.141593 * (a * a);
return (z);
}
float square (float b)
{
float y;
y = b * b;
return (y);
}
float rectangle (float c, float d)
{
float x;
x = c * d;
return (x);
}
float triangle (float e, float f)
{
float w;
w = (e * f) / 2;
return (w);
}
void exit ()
{
cout << "THANK YOU! GOODBYE!" << endl;
}
int main()
{
int x;
do
{
cout << "Please choose an option below: \n";
cout << "1. Area of Shapes\n";
cout << "2. Cost of your items\n";
cout << "3. Flood Control\n";
cout << "4. Fibonacci Numbers\n";
cout << "5. Addition Table\n";
cout << "6. Exit\n";
cin >> x;
if (x == 1)
{
system("cls");
float n;
float l;
float m;
float radius;
float side;
float length;
float width;
float base;
float height;
do
{
cout << "1 => Area of Circle" << endl;
cout << "2 => Area of Square" << endl;
cout << "3 => Area of Rectangle" << endl;
cout << "4 => Area of Trian1gle" << endl;
cout << "5 => Return to Main Menu" << endl;
cout << "0 => Exit" << endl;
cout << "Please enter number of your choice: ";
cin >> n;
system("cls");
{
if (n == 0)
{
exit ();
system("pause");
return 0;
}
else if (n == 1)
{
cout << "Enter radius of the circle: ";
cin >> radius;
l = circle (radius);
cout << "Area of the circle is: " << l << endl;
system("pause");
system("cls");
}
else if (n == 2)
{
cout << "Enter side of the square: ";
cin >> side;
cout << "Area of the square is: " << square (side) << endl;
system("pause");
system("cls");
}
else if (n == 3)
{
cout << "Enter length of the rectangle: ";
cin >> length;
cout << "Enter width of the rectangle: ";
cin >> width;
m = rectangle (length, width);
cout << "Area of the rectangle is: " << m << endl;
system("pause");
system("cls");
}
else if (n == 4)
{
cout << "Enter base of the triangle: ";
cin >> base;
cout << "Enter height of the triangle: ";
cin >> height;
cout << "Area of the triangle is: " << triangle (base, height) << endl;
system("pause");
system("cls");
}
else if (n == 5)
{
exit ();
}
else
cout << "Invalid number. Please enter a valid number below" << endl;
}
}
while (n != 0 && n != 5);
cout << endl << endl;
system("pause");
system("cls");
}
else if (x == 2)
{
system("cls");
string mystr;
float cost = 0;
float amount = 0;
float total;
cout << "Total Cost: P";
getline (cin, mystr);
stringstream(mystr) >> cost;
cout << endl;
total = cost * .06;
cout << "Sales Tax Value: P" << total << endl;
cout << endl;
cout << "Cost of Item: P" << cost + total << endl;
cout << endl;
cout << "Amount Paid: P";
getline (cin, mystr);
stringstream(mystr) >> amount;
cout << endl;
cout << "Total Amount Purchased: P" << cost << endl;
cout << "Sales Tax Value: P" << total << endl;
cout << "Total Amount + Sales Tax: P" << cost + total << endl;
cout << "Total Amount Paid: P" << amount << endl;
cout << "Change: P" << amount - (cost + total) << endl;
system("pause");
cout << endl;
cout << "THANK YOU! ENJOY YOUR MEAL!" << endl;
system("pause");
system("cls");
}
else if (x > 6)
cout << "Invalid Input";
else
{
system("pause");
return 0;
}
}
while (x != 6);
system("pause");
return 0;
}
EDIT
For the posters education
You do
switch (n) {
case 1:
//... Code for n == 1 - If long put into another function. If using local variables put code bloc in braces
break;
case 2:
// Diitto for n==2
default: // No match
// All other values of n not listed above
}
What went wrong
Say you type your menu selection:
2<Enter>
Then the content of the std::cin stream will be:
2\n
When your menu selection runs...
cin >> x;
...it reads a number off the line but doesn't consume any trailing whitespace nor the newline, so the remaining state content could be denoted like this:
\n
Then your code for menu option 2 starts running:
cout << "Total Cost: P";
getline (cin, mystr);
...the getline looks at std::cin and finds the left over \n mentioned above, and says "hey, an empty line - I'll set mystr to an empty string". Notice that it did not do what you'd hoped: namely wait for you to type some more input and read that into mystr.
How to fix it
Before calling getline(cin, mystr) you want to remove the left-over \n typed when entering the menu selection. The code changes for that (adding error handling too):
#include <limits>
...
cout << "Total Cost: P";
std::cin.ignore(std::numeric_limits<streamsize>::max(), '\n');
if (!std::getline(std::cin, mystr))
{
std::cerr << "unable to read mystr\n";
exit(1);
}
std::istringstream iss(mystr);
iss >> cost;
if (!iss)
{
std::cerr << "mystr doesn't contain a valid cost number\n";
exit(1);
}
How you could have found the problem
When you get stuck like this, try adding some "trace" statements to print out the values of variables and find where they differ from your expectation... that can at least give you a better idea how to isolate and describe the problem, and what to google for to fix it.
std::out << "mystr '" << mystr << "'\n";`
Try to use error handling like I've illustrated so the program stops (or prompts for better input) when there's a problem parsing the user's input.