error handling - Try and catch with while loop: jumps to catch block even after the input is correct only if the first input was incorrect - C++ -
i'm trying check if user has entered name correctly, or without space i.e. joe bloggs. cannot have special characters or numbers in name or pop error message i.e. jo3_bl0ggs. i'm trying if enter name in wrong format, error message alerted , program ask user enter name again, until enter correctly.
i'm using while loop if it's correct, change value of flag , break out of loop, if not i'll rerun setname() function asks name.
however problem i'm having if enter first time , it's incorrect, asks them enter name again , if second input correct message "welcome joe bloggs", loop continue , ask them enter name in again.
the way can avoid problem if first input correct, kind of defeats whole point of try , catch block.
below 2 functions i'm concerned with. if can point me in right direction, great. i'm new c++ why i'm bit confused this.
inputclass::inputclass(){//empty constructor} void inputclass::validatename(string name){ int flag = 1; while ( flag == 1){ try{ (int i=0; < name.length(); i++){ if (name[i] != ' '){ if (!isalpha(name[i])){ cout << "you have entered incorrectly. please try again. " << endl; cin.clear(); //i'm trying clear input buffer still doesn't work cin.ignore(256, '\n'); setname(); throw 0; //do need this? break; //do need breaks? }else if(i == name.length()-1){ cout << "welcome program " << name << endl; flag = 2; //break out of while loop break; //not sure if } } } }catch (int e){ cout << "there's been error" << endl; setname(); //until input correct, ask user name. } } } void inputclass::setname(){ string name; cout << "please enter name: " << endl; getline(cin, name); validatename(name); }
my honest opinion algorithm logic wrong. validation should done consequence of input. input should decision point of recycling on validation failure
1. write simple validation function
this easier may think, in particular since standard library provides neat algorithms doing of iteration work you.
2. integrate validation function exclusively in setname()
; not opposite.
your input mechanics should take said-input, validate, , if invalid, loop on input. validator should exclusively returning yea or nay. leave input mechanics input function, , don't trigger them validator. validator that; validating, not cycling input loops.
the first of these simple since standard library provides of algorithms need. sample below uses functor this, c++11 lambda instead:
struct is_not_space_or_alpha { bool operator()(char c) const { return c != ' ' && !std::isalpha(static_cast<unsigned char>(c)); } }; static bool is_valid_name(const std::string& name) { return !name.empty() && name.end() != std::find_if(name.begin(), name.end(), is_not_space_or_alpha()); }
with that, setname()
becomes location validation consequence of input; validation doesn't internally trigger more input. left caller (setname()
) decide:
std::string name; while (true) { std::cout << "please enter name: "; std::flush(std::cout); if (std::getline(std::cin, name) && is_valid_name(name)) { std::cout << "welcome program " << name << "!\n"; break; } std::cout << "you have entered incorrectly. please try again. \n"; std::cin.clear(); }
sample output
please enter name: monkey777 have entered incorrectly. please try again. please enter name: wiley coyote welcome program wiley coyote!
the bottom line: don't trigger input validation. instead, trigger validation from input , act accordingly.
Comments
Post a Comment