Handling Input to Avoid Program Crashes - xfgr.com Click here to Skip to main content

Handling Input to Avoid Program Crashes

This program will help you understand how you can avoid crashes for unexpected input.
Sign Up to vote for this article
Add a reason or comment to your vote: x
1
answer
3.5/5
2 votes
601
views
Tags: C++

Introduction

This article is about validating input in order to avoid crashing when invalid input is given by the user.

Background

Everyone has had, at one point of time, experienced a crash due to incorrect input. This is an example of one way it could be handled in C++.

Using the Code

You can create a project using the attached CPP code. Compile the application and try to enter string where number is required. The program will complain instead of crashing. Just play around with it.

		/*
Developed by	: Dhruvkumar Rangunwala
Email : instrukahero@yahoo.com
*/
#include <iostream> #include <string> #include <cctype> using namespace std;
bool CheckIfNumber(string , int, int&);
const int asciiStartForDigit(48);
int main()
{
double celcius, fahrenheit;
string choice, numberEntered;
int numberEnteredVerified, multiplesOf10 = 1, choiceInNumber;

do {
system("cls");
cout << "This program converts C -> F and F -> C temperature unit" << endl;
cout << "Enter 1 for C -> F" << endl;
cout << "Enter 2 for F -> C" << endl;
cout << "Enter x or X to exit" << endl;
cin >> choice;
if ((choice.at(0) == 'x' choice.at(0) == 'X') && choice.length() == 1)
{
break;
}
numberEnteredVerified = 0;
if(CheckIfNumber(choice, multiplesOf10, numberEnteredVerified))
{
cout << "Choice entered is :" << numberEnteredVerified << endl;
switch(numberEnteredVerified)
{
case 1:
cout << "Enter temperature to convert from C to F:";
break;
case 2:
cout << "Enter temperature to convert from F to C:";
break;
default:
cout << "You did not enter choice as 1 or 2\n";
system("pause");
continue;
}
cin >> numberEntered;
}
else {
cout << "\nYou did not enter a number for choice\n\n\n";
system("pause");
continue;
}
choiceInNumber = numberEnteredVerified;
numberEnteredVerified = 0;
if(CheckIfNumber(numberEntered, multiplesOf10, numberEnteredVerified))
{
cout << "Number entered is :" << numberEnteredVerified << endl;
switch(choiceInNumber)
{
case 1:
celcius = numberEnteredVerified;
fahrenheit = (9.0/5) * celcius + 32;
cout << "Celcius " << celcius <<
" when converted to Fahrenheit is " << fahrenheit << endl;
break;
case 2:
fahrenheit = numberEnteredVerified;
celcius = (fahrenheit - 32) * (5.0/9);
cout << "Fahrenheit " << fahrenheit << " when converted to Celcius is " << celcius << endl;
break;
}
system("pause");
}
else {
cout << "\nYou did not enter a number for conversion\n\n\n";
system("pause");
continue;
}
}while (true);

cout << "\n\n\nExiting the program\n\n\n";
}
bool CheckIfNumber(string numberEntered, int multiplesOf10, int& numberEnteredVerified)
{
char numberEnteredToChar[10];
size_t i;
strcpy(numberEnteredToChar, numberEntered.c_str());
for(i = 0; i < strlen(numberEnteredToChar); i++)
{
if(!(isdigit(numberEnteredToChar[i])))
{
return false;
}
else {
numberEnteredVerified = (numberEnteredVerified * multiplesOf10) +
((int) numberEnteredToChar[i] - asciiStartForDigit);
multiplesOf10 *= 10;
}
}
return true;
}
Posted 14 Jun '10 6:55 AM
Edited 21 Jun '10 8:31 AM
Revision 2

5.00 / 5, 1 vote
Sign Up to vote for this article
Add a reason or comment to your vote: x
Instead of doing what the original author does (which is read a string and convert it manually into a number) why not use streams properly?

When a program wants a number, read a number and then check the stream state is still good. If it's not you know the user has entered something that's not a number. If the stream's in an error state you can clear the error, bin the rest of the input and ask them to start again...

#include <iostream>

#include <string>


int main()
try {
while( std::cin )
{
std::cout << "I convert temperatures from centigrade to fahrenheit\n" "Please enter a temperature in centigrade for me" " to convert(CTRL+Z to exit): ";

double centigrade = 0.0;
std::cin >> centigrade;
if( std::cin.good() )
{
std::cout << "You entered " << centigrade << "C\n" << "That's equivalent to " << centigrade * 9.0 / 5.0 + 32 << "F" << std::endl;
}
else if( !std::cin.eof() )
{
std::cout << "You're such a kidder!" << std::endl;
std::cin.clear();
std::string junk;
std::getline( std::cin, junk );
}
}
}
catch( std::exception &e )
{
std::cout << "Something went wrong: " << e.what() << std::endl;
}
catch( ... )
{
std::cout << "Something went wrong, no idea what!" << std::endl;
}

While it's still possible to stuff up the input to the program you won't get anything that causes it to crash. (Please treat this assertion as a challenge and if you manage it I can improve the code).

Oh, and if you're on Linux/UNIX you want to press CTRL+D to exit the program.

Cheers,

Ash

PS: Edited to add the include directives, the compiler considers it a bit rude to leave them out.

PPS: Edited again so the angle brackets showed up... grrr...
  Revision 4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Hint: For improved responsiveness use Internet Explorer 4, Firefox or above. Ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
FAQ FAQ   
Noise Tolerance  Layout  Per page   
  (Refresh) 
-- There are no messages in this forum --

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   


Last Updated 26 Mar 2009
Web23 2.3.0027 Advertise Privacy