I am having some major issues error checking user input inside a do while loop. I want to post the code for it but I'm not sure how to do it on here. If someone could help me with that than we can move on with the help with the actual code :P
copy and paste the code into the text field, but make sure you use the format option for code named 'source code' (those tools should be next to the text field).
There that should do it. It's a mass conversion program that goes from imperial to metric and then back. I have the error checking working just fine for the unit of measurement its checking the int is the issue. Try running this and see what you can come up with.
/* Christopher Reath
May 11th, 2012
This program converts a mass unit of measurement into another type of measurement
*/
#include<iostream>
#include<string>
#include<sstream>
usingnamespace std;
int main()
{
#if defined(_DEBUG)
int dbgFlags = ::_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
// Bitwise or. check block integrity on every memory call
dbgFlags |= _CRTDBG_CHECK_ALWAYS_DF;
// Don't always remove blocks on delete
dbgFlags |= _CRTDBG_DELAY_FREE_MEM_DF;
// Check for memory leak at process termination
dbgFlags |= _CRTDBG_LEAK_CHECK_DF;
_CrtSetDbgFlag(dbgFlags);
#endif
char answer;
double mass, convertedMass = 0;
string unit, input, convertedUnit;
int done = 0;
// do while loop for Input validation and convertions
do
{
// Prompt the user for input
cout << "Enter the mass and unit of measurement you wish to convert\n";
cout << "(g, kg, lb, oz, tonne, ton, eg. 10ton)\n";
cout << "No spaces in between the mass and unit: ";
cin >> input;
istringstream iss(input);
iss >> mass >> unit;
if(!cin.good())
{
cout << "You've entered the wrong data type.\n""Please enter a number.";
}
cin.clear();
cin.sync();
if(unit == "kg") // Converts from kilograms to pounds
{
convertedMass = mass * 2.20462262;
convertedUnit = "lb";
}
elseif(unit == "lb") // Converts from pounds to kilograms
{
convertedMass = mass * 0.45359237;
convertedUnit = "kg";
}
elseif(unit == "g") // Converts from grams to ounces
{
convertedMass = mass * 0.0352739619;
convertedUnit = "oz";
}
elseif(unit == "oz") // Converts from ounces to grams
{
convertedMass = mass * 28.3495231;
convertedUnit = "g";
}
elseif(unit == "tonne") // Converts from tonne to short ton
{
convertedMass = mass * 1.10231131;
convertedUnit = "ton";
}
elseif(unit == "ton") // Converts from short ton to tonne
{
convertedMass = mass * 0.90718474;
convertedUnit = "tonne";
}
else
{
cout << "Not a valid unit of measurement.\n"; // Error check
}
// Output the converted mass to the user
cout << mass << unit << " is equal to " << convertedMass << convertedUnit << endl;
// Ask if you want to do another convertion after already completing one
cout << "\nReady to do some convertions? (yes or no): ";
cin >> answer;
cout << endl;
if(answer == 'n' || answer == 'N')
{
++done;
}
cin.clear(); // Flush the buffer
cin.sync();
}while(done !=1); // End do while loop
return 0;
}
Tip: Explain, in detail, the problem you're having to increase your odds of getting a quick response. Supplying examples of input that you wish to handle correctly but don't would've been useful.
Tip: Don't 'bump' your post an hour after you make it.
cin.sync() is not guaranteed to do anything useful.
I would probably change:
1 2 3 4 5 6 7
if(!cin.good())
{
cout << "You've entered the wrong data type.\n""Please enter a number.";
}
cin.clear();
cin.sync();
to look like:
1 2 3 4 5 6 7 8 9 10 11 12 13
if ( !cin )
{
std::cerr << "You've entered the wrong data type.\n""Please enter a number.";
cin.clear() ;
// ignore the rest of the offending line:
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n' ) ;
// skip to the loop condition
continue ;
}
Ok the real problem I am having is when someone enters something like "ukg" into my program (kg being kilograms the unit of measurement. u being someone entering a letter instead of a number for the mass) I want the program to run that if statement and the text that is inside it and return them to the prompt to enter the mass and unit again. As of right now if I do enter "ukg" then the program seems to not even run the if(!cin.good()) statement and go to the end of the if else statement where my else is the error check of my unit of measurement and prints out that cout instead. Also even if the program error checks it still likes to show the program trying to convert whatever it is they entered which outputs a bunch of garbage. If this is not clear enough please tell me what would make it clearer.
Yes I did and again it just skips right by the error check IF and this time instead of even saying it is an invalid input it just outputs the same conversion I did just before inputing "ukg" so now it doesn't even read it as an error AND also doesn't flush the buffer since I got rid of cin.sync
#include<iostream>
#include<string>
#include<sstream>
usingnamespace std;
int main()
{
char answer;
double mass, convertedMass = 0;
string unit, input, convertedUnit;
int done = 0;
// do while loop for Input validation and convertions
do
{
// Prompt the user for input
cout << "Enter the mass and unit of measurement you wish to convert\n";
cout << "(g, kg, lb, oz, tonne, ton, eg. 10ton)\n";
cout << "No spaces in between the mass and unit: ";
cin >> input;
istringstream iss(input);
iss >> mass >> unit;
if(mass > 0) // Error check to confirm the user has inputed a proper value
{
if(unit == "kg") // Converts from kilograms to pounds
{
convertedMass = mass * 2.20462262;
convertedUnit = "lb";
cout << mass << unit << " is equal to " << convertedMass << convertedUnit << endl << endl; // Outputs conversion
}
elseif(unit == "lb") // Converts from pounds to kilograms
{
convertedMass = mass * 0.45359237;
convertedUnit = "kg";
cout << mass << unit << " is equal to " << convertedMass << convertedUnit << endl << endl; // Outputs conversion
}
elseif(unit == "g") // Converts from grams to ounces
{
convertedMass = mass * 0.0352739619;
convertedUnit = "oz";
cout << mass << unit << " is equal to " << convertedMass << convertedUnit << endl << endl; // Outputs conversion
}
elseif(unit == "oz") // Converts from ounces to grams
{
convertedMass = mass * 28.3495231;
convertedUnit = "g";
cout << mass << unit << " is equal to " << convertedMass << convertedUnit << endl << endl; // Outputs conversion
}
elseif(unit == "tonne") // Converts from tonne to short ton
{
convertedMass = mass * 1.10231131;
convertedUnit = "ton";
cout << mass << unit << " is equal to " << convertedMass << convertedUnit << endl << endl; // Outputs conversion
}
elseif(unit == "ton") // Converts from short ton to tonne
{
convertedMass = mass * 0.90718474;
convertedUnit = "tonne";
cout << mass << unit << " is equal to " << convertedMass << convertedUnit << endl << endl; // Outputs conversion
}
else
{
cout << "Not a valid unit of measurement.\n"; // Error check
}
// Ask if you want to do another convertion after already completing one
cout << "\nReady to do some convertions? (yes or no): ";
cin >> answer;
cout << endl;
if(answer == 'n' || answer == 'N')
{
++done;
}
}
else
{
cout << "You have not a number for this convertion\n\n";
}
cin.clear(); // Flush the buffer and resets mass so input can be checked
cin.sync();
mass = -1;
}while(done !=1); // End do while loop
return 0;
}
Ahh, I didn't look at the code closely enough. The error state would actually occur in iss, not cin (unless you redirected from file, I suppose, and it ran into eof.)
Here's an alternate version, if you should care to actually check error states (important parts in bold):
#include <limits>
#include<iostream>
#include<string>
#include<sstream>
usingnamespace std;
int main()
{
char answer;
double mass, convertedMass = 0;
string unit, input, convertedUnit;
int done = 0;
// do while loop for Input validation and convertions
do
{
charconst* prompt = "Enter the mass and unit of measurement you wish to convert\n""(g, kg, lb, oz, tonne, ton, eg.10ton)\n""No spaces in between the mass and unit: " ;
// Prompt the user for input
cout << prompt ;
while ( cin >> input )
{
istringstream iss(input);
if ( !(iss >> mass >> unit) || mass <= 0.0 )
std::cout << "You didn't enter a valid number or didn't supply a unit of measurement.\n" << prompt ;
elsebreak ;
}
if(unit == "kg") // Converts from kilograms to pounds
{
convertedMass = mass * 2.20462262;
convertedUnit = "lb";
cout << mass << unit << " is equal to " << convertedMass << convertedUnit << endl << endl; // Outputs conversion
}
elseif(unit == "lb") // Converts from pounds to kilograms
{
convertedMass = mass * 0.45359237;
convertedUnit = "kg";
cout << mass << unit << " is equal to " << convertedMass << convertedUnit << endl << endl; // Outputs conversion
}
elseif(unit == "g") // Converts from grams to ounces
{
convertedMass = mass * 0.0352739619;
convertedUnit = "oz";
cout << mass << unit << " is equal to " << convertedMass << convertedUnit << endl << endl; // Outputs conversion
}
elseif(unit == "oz") // Converts from ounces to grams
{
convertedMass = mass * 28.3495231;
convertedUnit = "g";
cout << mass << unit << " is equal to " << convertedMass << convertedUnit << endl << endl; // Outputs conversion
}
elseif(unit == "tonne") // Converts from tonne to short ton
{
convertedMass = mass * 1.10231131;
convertedUnit = "ton";
cout << mass << unit << " is equal to " << convertedMass << convertedUnit << endl << endl; // Outputs conversion
}
elseif(unit == "ton") // Converts from short ton to tonne
{
convertedMass = mass * 0.90718474;
convertedUnit = "tonne";
cout << mass << unit << " is equal to " << convertedMass << convertedUnit << endl << endl; // Outputs conversion
}
else
{
cout << "Not a valid unit of measurement.\n"; // Error check
}
// Ask if you want to do another convertion after already completing one
cout << "\nReady to do some convertions? (yes or no): ";
cin >> answer;
cout << endl;
// take care of someone entering more than one letter for answer.
if ( cin.peek() != '\n' )
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n' ) ;if(answer == 'n' || answer == 'N')
{
++done;
}
}while(done !=1); // End do while loop
return 0;
}