iccaros Posted April 15, 2005 Report Share Posted April 15, 2005 ok I have a problem, I have a program that runs but only if you put the correct type of input.. ie I have a int feetif on cin >> feet the user puts: a it put a loop that confuses the program requiring cntrl-c to stopis there a way to test this varable to see if the input type is correct?also I am using -1 as a end condetion (teachers choice)while it runs, And I know that the teacher would accept it as its is as the book has no mention of testing input. I do not think its a good ideal to put out software if the user can mess it up by putting a wong input type/ Quote Link to post Share on other sites
Matt Posted April 15, 2005 Report Share Posted April 15, 2005 I think what you are looking for are 'checks'. Try reading here:http://www.besttechie.net/forums/index.php...indpost&p=14082 for more info on those. (thats the post talking about them, but you may need to read the whole thread) I never got to understanding them yet, but see if that helps.Matt Quote Link to post Share on other sites
jcl Posted April 15, 2005 Report Share Posted April 15, 2005 (edited) Right, the fail() member function will do the trick.$ cat t.cc#include <iostream>using namespace std;int main(){ while (true) { int i; // Prompt cout << "val: "; // Flush cout to force prompt to be printed cout.flush(); cin >> i; if (cin.fail()) { cerr << "invalid input" << endl; // Clear failure/error flags cin.clear(); // Drop character that caused failure cin.ignore(); } else { if (i != -1) { cout << "value: " << i << endl; } else { return 0; } } } return 0;}$ g++ t.cc$ ./a.out val: 1value: 1val: 2value: 2val: 3value: 3val: ainvalid inputval: -1$There's no reliable way to use the value returned by operator>>() to determine if there was a failure. Edited April 15, 2005 by jcl Quote Link to post Share on other sites
iccaros Posted April 16, 2005 Author Report Share Posted April 16, 2005 I get everything you did (thanks to comments.) but I do not get the two return 0;if ?I have a return 0 at the end do I need it in a else.. or can I dope the else all together??is that even aprt of the error checking as my if ( != -1) looks like this (noticed the check OS function I barrowed from you)#include <iostream>#include <cstdlib> //needed for system callsusing namespace std;// this is used instead of calling all the using std::cout or defining each std outvoid clear_screen() // this is for portability of system call you must us the -DUNIX or -DWIN32 option for gcc{#if defined WIN32 // compiler replaces clear_screen() with system("cls"); if -DWIN32 is used with gcc system("cls");#elif defined UNIX // compiler replaces clear_screen() with system("clear") if -DUNIX is used with gcc system("clear");#endif}//Main Functionint main(){ int miles, MgCounter = 0;//initalize varables for holding miles and the counter for loop double gallons, totalMg, average, finalMg; //initalize double for decmial point //clear screen call clear_screen();//call the correct clearscreen function for your system based on the -D compile option for VC++ ?? //process phase, also loads one input before the loop cout << "Enter the Gallons used (-1 to end) : ";//prompt for gallons cin >> gallons;//input for gallons //start while not loop while (gallons != -1) { cout << "Enter Miles Driven: "; cin >> miles;//prompt for miles //start math average = miles / gallons;//divide miles by gallons to get average totalMg += average;// adds average to totalMg ++MgCounter;//increment MgCounter cout << "The Miles / Gallon for this tank was " << average << endl;//output this tank //next round of input cout << "\nEnter the Gallons used (-1 to end) : ";//prompt for gallons cin >> gallons; //input for gallons }//end while if (MgCounter != 0) { finalMg = totalMg / MgCounter; // math for final calculation cout << "\nThe overall average miles/gallon was " << finalMg << endl; } // end this part of if statment go to else else cout << "you did not enter any information to calculate" << endl; return 0;// returns function competion value} if I got what you said it should look like this#include <iostream>#include <cstdlib> //needed for system callsusing namespace std;// this is used instead of calling all the using std::cout or defining each std outvoid clear_screen() // this is for portability of system call you must us the -DUNIX or -DWIN32 option for gcc{#if defined WIN32 // compiler replaces clear_screen() with system("cls"); if -DWIN32 is used with gcc system("cls");#elif defined UNIX // compiler replaces clear_screen() with system("clear") if -DUNIX is used with gcc system("clear");#endif}// function to check if a bad input was entered in to program, and ends programint error_check(){ if (cin.fail()) { cerr << "invalid input" << endl; // Clear failure/error flags cin.clear(); // Drop character that caused failure cin.ignore(); }//end if return 0;}//Main Functionint main(){ int miles, MgCounter = 0;//initalize varables for holding miles and the counter for loop double gallons, totalMg, average, finalMg; //initalize double for decmial point //clear screen call clear_screen();//call the correct clearscreen function for your system based on the -D compile option for VC++ ?? //process phase, also loads one input before the loop cout << "Enter the Gallons used (-1 to end) : ";//prompt for gallons cin >> gallons;//input for gallons error_check(); //start while not loop while (gallons != -1) { cout << "Enter Miles Driven: "; cin >> miles;//prompt for miles error_check(); //start math average = miles / gallons;//divide miles by gallons to get average totalMg += average;// adds average to totalMg ++MgCounter;//increment MgCounter cout << "The Miles / Gallon for this tank was " << average << endl;//output this tank //next round of input cout << "\nEnter the Gallons used (-1 to end) : ";//prompt for gallons cin >> gallons; //input for gallons error_check(); }//end while if (MgCounter != 0) { finalMg = totalMg / MgCounter; // math for final calculation cout << "\nThe overall average miles/gallon was " << finalMg << endl; } // end this part of if statment go to else else cout << "you did not enter any information to calculate" << endl; return 0;// returns function competion value.. really not needed for main but makes a nice output for other programs} This is primive in doing this but it has a effect that works.. I just need to adapt it to work better and have it exit the program or maybe the inputs need to be functions?? so I can rerun them incase of error Quote Link to post Share on other sites
iccaros Posted April 16, 2005 Author Report Share Posted April 16, 2005 I think what you are looking for are 'checks'. Try reading here:http://www.besttechie.net/forums/index.php...indpost&p=14082 for more info on those. (thats the post talking about them, but you may need to read the whole thread) I never got to understanding them yet, but see if that helps.Matt thanks ..I had read that but I could not see the answer in their.. untill now.. sometimes I'm slow Quote Link to post Share on other sites
jcl Posted April 16, 2005 Report Share Posted April 16, 2005 (edited) I get everything you did (thanks to comments.) but I do not get the two return 0;if ?I have a return 0 at the end do I need it in a else.. or can I dope the else all together??The one at the end of main() is force of habit; the first thing I write in main() is a return statement. It doesn't do anything in this case, but it doesn't hurt.The one in the else, on the other hand, is responsible for terminating the program when it receives a -1, so it has be there. (Or something has to be there anyway; it could replaced with some other transfer of control to break out of the while loop. Break or goto would work.)as my if ( != -1) looks like this (noticed the check OS function I barrowed from you)That's fine. Probably better, actually. I debated how to write the loop but decided that it would clearest if I made all the tests explicit. I don't really like the cascading conditionals but they're easier to read than something like#include <iostream>using namespace std;int main(){ int i = 0; while (cout << "val: " << flush, cin >> i, i != -1 && !cin.eof()) { cin.good() ? cout << "value: " << i << endl : (cin.clear(), cin.ignore(), cerr << "invalid input" << endl); } return 0;}Aside: It occured to me that I'd forgotten to check for EOF earlier.This is primive in doing this but it has a effect that works.. I just need to adapt it to work better and have it exit the program or maybe the inputs need to be functions?? so I can rerun them incase of errorWhatever works. There are a lot of good ways to do this sort thing; all that matters is that you're comfortable with your solution. I'd probably wrap the input stuff up in generic prompt function (I do like writing prompt functions). Edited April 16, 2005 by jcl Quote Link to post Share on other sites
iccaros Posted April 16, 2005 Author Report Share Posted April 16, 2005 xorry, by primitive I ment my soultion to use the saem error check to all input when not all input is the same Quote Link to post Share on other sites
iccaros Posted April 16, 2005 Author Report Share Posted April 16, 2005 on other thing.. I would need to declare variables outside of main if I made prompt functions correct? Quote Link to post Share on other sites
jcl Posted April 16, 2005 Report Share Posted April 16, 2005 (edited) on other thing.. I would need to declare variables outside of main if I made prompt functions correct?Nope, the function is all you need. For simple integer prompts this would suffice:int prompt(const string& s){ while (true) { int val; cout << s << flush; cin >> val; if (cin.fail()) { cerr << "invalid input"; cin.clear(); cin.ignore(); } else { return val; } }}usage:int val;while ((val = prompt("enter value: ")) != -1) { // etc} Edited April 16, 2005 by jcl Quote Link to post Share on other sites
iccaros Posted April 16, 2005 Author Report Share Posted April 16, 2005 Thanks I need to play with it.. I think I understand but I probaly do not.. i see why people hate ths stuff. BASIC take me away.. Quote Link to post Share on other sites
iccaros Posted April 16, 2005 Author Report Share Posted April 16, 2005 (edited) ok I think I understand..this is a function creaded before main()int prompt( const string& s){ while (true) { int val; cout << s << flush; cin >> val; if (cin.fail()) { cerr << "invalid input"; cin.clear(); cin.ignore(); } else { return val; } }}then in main()I have int val;while ((val = prompt("enter value: ")) != -1) { // etc}but for my understanding... the while (val ) test aginst the value of the return of prompt()and the prompt("enter val: ") tell the fiunction prompt to put enter val: into s , which is declared as a const string& type.. hmmm....so if I did a double val insted of int I could then have my floting point and my function..also the return val now explains how main know's the value of val..back to playing..thanks.. Edited April 16, 2005 by iccaros Quote Link to post Share on other sites
iccaros Posted April 18, 2005 Author Report Share Posted April 18, 2005 ok here is my final code with error checking.. Could I have made it smaller?#include <iostream>#include <cstdlib>using namespace std;// this is for portability of system call you must us the -DUNIX or -DWIN32 option for gcc// compiler replaces clear_screen() with system("cls"); if -DWIN32 is used with gcc// compiler replaces clear_screen() with system("clear") if -DUNIX is used with gccvoid clear_screen(){#if defined WIN32 system("cls");#elif defined UNIX system("clear");#endif}//this is the prompt for gallons input with type error checkingdouble prompt_gallons ( const string& s ){ while (true) { double gallons; cout << s << flush; cin >> gallons; //error check for correct type if (cin.fail()) { cerr << "invalid input \n"; cin.clear(); cin.ignore();} else return gallons;}}//this is the prompt for miles input with error checkingdouble prompt_miles ( const string& t ){ while (true) { double miles; cout << t << flush; cin >> miles; //error check for correct type if (cin.fail()) { cerr << "invalid input \n"; cin.clear(); cin.ignore();} else return miles;}}//main loopint main (){ double val, miles, MgTotal , average, finalMg, gallons; int MgCounter = 0; clear_screen(); while ((gallons = prompt_gallons("enter gallons used (enter -1 to end): ")) != -1 ) { miles = prompt_miles("enter miles: "); average = miles / gallons; MgTotal += average; ++MgCounter; cout << "The Average Miles per Gallon for this tank was " << average << endl; } if (MgCounter != 0) { finalMg = MgTotal / MgCounter; cout << "\nThe overall average miles/gallon was " << finalMg << endl; } else cout << "you did not enter any information:" << endl;return 0;} Quote Link to post Share on other sites
jcl Posted April 19, 2005 Report Share Posted April 19, 2005 Could I have made it smaller?You can always make it smaller but usually you shouldn't Looks fine. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.