Reputation: 13
So, I have several fields to fill in with numerals. And if I try to fill in the input with letters (ex. 'noway' or 'gg1337' - it makes and error and asks for a valid number (without letters for ex. '13' or '1500000').
BUT there is one problem, if I start to fill the input with numbers and then I add some letters (for ex. '12nowshithappens'), this jumps to the next field of input, thinking it is a valid number, but showing an error in the next input field.
Here is the function code:
int appled()
{
cin >> appleds;
while(cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
cout << "An arror occured!\nPlease, enter a valid number: ";
cin >> appleds;
}
return appleds;
}
If I described something wrong - here is the full code of my test program :)
// exZerry presents
#include <iostream>
#include <conio.h>
int apples;
int fruit;
int oranges;
int x;
int appleds;
int orangeds;
using std::cout;
using std::cin;
using std::endl;
using std::numeric_limits;
using std::streamsize;
char newline = '\n';
bool ok;
bool ok2;
bool ok3;
int appled() //Function to receive 'apples' input
{
cin >> appleds;
while(cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
cout << "An arror occured!\nPlease, enter a valid number: ";
cin >> appleds;
}
return appleds;
}
int oranged() //Function to receive 'oranges' input
{
cin >> orangeds;
while(cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
cout << "An arror occured!\nPlease, enter a valid number: ";
cin >> orangeds;
}
return orangeds;
}
int main()
{
ok = ok2 = ok3 = false; //Some testing
while(!ok2) //Actual program loop
{
x = 0; // Dropping program restart.
//cout << "-----------------------" << endl;
//cout << "DEBUG MODE: " << x << endl;
//cout << "-----------------------" << endl;
cout << "=====================================================" << endl;
cout << "Enter apples: ";
apples = appled();
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n'); //Now we have apples
cout << "Enter oranges: ";
apples = oranged();
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n'); //And now we have oranges
cout << "\n=====================================================" << endl;
cout << "Calculating..." << endl;
cout << "=====================================================" << endl;
fruit = apples + oranges;
cout << "In total we have " << fruit << " fruit" << endl;
cout << "=====================================================" << endl;
cout << newline;
//Option to go out or continue the loop
//If you enter 1 - resets the program, any other char - exit
cout << "Go out? (1 - 'No', Others - 'Yeap'):" << " ";
cin >> x;
cout << newline;
// ok2 = true;
if (x == 1)
{
cout << "Continue the program..." << endl;
//cout << "-----------------------" << endl;
//cout << "DEBUG MODE: " << x << endl;
//cout << "-----------------------" << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
ok = false;
ok3 = false;
continue;
}
if (x == 0)
{
cout << "Shutting down the app..." << x << endl;
//cout << "-----------------------" << endl;
//cout << "DEBUG MODE: " << x << endl;
//cout << "-----------------------" << endl;
break;
}
else
{
cout << "Shutting down the app..." << x << endl;
//cout << "-----------------------" << endl;
//cout << "DEBUG MODE: " << x << endl;
//cout << "-----------------------" << endl;
break;
}
}
cout << "Press any key to exit :D" << endl;
getch();
return 0;
}
Upvotes: 1
Views: 1078
Reputation: 13
So I tried and it worked, thanks, Batmaaaan :D
Adding full working code. What's it doing? Simple: When you wish to count something and you obviously do not want to count letters in your program, this might help you to do it, while styding C++ or whatever. Some basics, I guess, for everyone =)
Made and tested in Visual Studio 2012. Took some time to gather every peace of code in one place.
// exZerry presents
// Apples & Oranges V2.1
#include <iostream>
#include <conio.h>
int apples;
int juce;
int oranges;
int x;
int appleds;
int orangeds;
using std::cout;
using std::cin;
using std::endl;
using std::numeric_limits;
using std::streamsize;
using std::locale;
char newline = '\n';
bool ok;
bool ok2;
bool ok3;
class num_get : public std::num_get<char>
{
public:
iter_type do_get( iter_type it, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, long& v) const
{
auto& ctype = std::use_facet<std::ctype<char>>(str.getloc());
it = std::num_get<char>::do_get(it, end, str, err, v);
if (it != end && !(err & std::ios_base::failbit)
&& ctype.is(ctype.alpha, *it))
err |= std::ios_base::failbit;
return it;
}
};
/*
int appled()
{
cin >> appleds;
while(cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
cout << "An arror occured!\nPlease, enter a valid number: ";
cin >> appleds;
}
return appleds;
}
int oranged()
{
cin >> orangeds;
while(cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
cout << "An arror occured!\nPlease, enter a valid number: ";
cin >> orangeds;
}
return orangeds;
}
*/
int main()
{
cout << "=====================================================" << endl;
cout << "Welcome to exZerry's 'Apples & Oranges V2'" << endl;
cout << "=====================================================" << endl;
cout << newline;
cout << newline;
ok = ok2 = ok3 = false;
while(!ok2)
{
x = 0;
//cout << "-----------------------" << endl;
//cout << "DEBUG MODE: " << x << endl;
//cout << "-----------------------" << endl;
cout << "=====================================================" << endl;
cout << "Enter apples: ";
// apples = appled();
locale orig(cin.getloc());
cin.imbue(locale(orig, new num_get));
while (!(cin >> apples)) {
cout << "An arror occured!\nPlease, enter a valid number: ";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
}
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
cout << "Enter oranges: ";
// oranges = oranged();
//std::locale orig(std::cin.getloc());
cin.imbue(locale(orig, new num_get));
while (!(cin >> oranges)) {
cout << "An arror occured!\nPlease, enter a valid number: ";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
}
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
cout << "\n=====================================================" << endl;
cout << "Calculating..." << endl;
cout << "=====================================================" << endl;
juce = apples + oranges;
cout << "In total we have " << juce << " fruit" << endl;
cout << "=====================================================" << endl;
cout << newline;
cout << "Go out? (1 - 'No', Others - 'Yeap'):" << " ";
cin >> x;
cout << newline;
// ok2 = true;
if (x == 1)
{
cout << "Continue the program..." << endl;
//cout << "-----------------------" << endl;
//cout << "DEBUG MODE: " << x << endl;
//cout << "-----------------------" << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
ok = false;
ok3 = false;
continue;
}
if (x == 0)
{
cout << "Shutting down the app..." << x << endl;
//cout << "-----------------------" << endl;
//cout << "DEBUG MODE: " << x << endl;
//cout << "-----------------------" << endl;
break;
}
else
{
cout << "Shutting down the app..." << x << endl;
//cout << "-----------------------" << endl;
//cout << "DEBUG MODE: " << x << endl;
//cout << "-----------------------" << endl;
break;
}
}
cout << "Press any key to exit :D" << endl;
getch();
return 0;
}
Upvotes: 0
Reputation: 96875
You can make your own facet that parses character sequence like that add invalid. Like this:
class num_get : public std::num_get<char>
{
public:
iter_type do_get( iter_type it, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, long& v) const
{
auto& ctype = std::use_facet<std::ctype<char>>(str.getloc());
it = std::num_get<char>::do_get(it, end, str, err, v);
if (it != end && !(err & std::ios_base::failbit)
&& ctype.is(ctype.alpha, *it))
err |= std::ios_base::failbit;
return it;
}
};
Now you can install it into your stream:
std::locale orig(std::cin.getloc());
std::cin.imbue(std::locale(orig, new num_get));
while (!(std::cin >> appleds)) {
// input was not entirely numeric
}
// input was entirely numeric
Upvotes: 1