How do I validate integer input? - c++

So I was just making this little calculator program for a game my brother plays just because I was bored. I took a c++ course last semester in college (now taking a java course which I find a bit more confusing) and I just found it fun to make these little programs. Well like usual I'm getting carried away and must be a perfectionist and this is really bothering me.
Now in this game, and like in real life, numbers are seperated by commas to obviously make it easier to read. Because of this, that's mostly how numbers are going to be inputted into the calculator by my brother. Now I could just tell him to not put in any commas when typing in the number and put it in the prompt that there should not be any commas but even then you can't be sure. Even so, it would be best if the code just doesn't mess up every time something that's not a number is put in.
What I've got so far is pretty good. if you put in just letters it will prompt the user again and if you put letters in AFTER the numbers only (not inbetween, that messes it up i found) then it will ignore those letters and work properly. If you put in commas though, it always returns the same thing (0 and 5) although that could be what I'm putting in. I have no idea if the comma is acting as a cut off point or what. Here's the code for getting the integers:
#include <iostream>
using namespace std;
int main() {
int numberofbones, amountofxp, comparableDrag, comparableBaby, comparableDragNoAltar, comparableBigNoAltar, comparableBabyNoAltar;
double comparableBig;
char Gildedaltar, BoneSelection, replay;
bool bFail;
do{
cout << "How many bones do you have?: ";
cin >> numberofbones;
bFail = cin.fail();
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
} while (bFail == true);
do{
cout << "How much XP do you need?: ";
cin >> amountofxp;
bFail = cin.fail();
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
} while (bFail == true);
cout << "Are you using a Gilded Altar? (Y/N) ";
prompt:
cin >> Gildedaltar;
comparableDrag = amountofxp / 252;
comparableBig = amountofxp / 52.5;
comparableBaby = amountofxp / 105;
comparableDragNoAltar = amountofxp / 72;
comparableBigNoAltar = amountofxp / 15;
comparableBabyNoAltar = amountofxp / 30;
if (Gildedaltar == 'y' || Gildedaltar == 'Y') {
system("cls");
cout << "What bones will you be using: " << endl;
cout << "a) Dragon Bones " << endl;
cout << "b) Big Bones " << endl;
cout << "c) BabyDragon Bones " << endl;
cin >> BoneSelection;
if (BoneSelection == 'a' || BoneSelection == 'A') {
cout << endl << "With Dragon Bones you need " << comparableDrag << " Bones" << endl;
if (comparableDrag < numberofbones) {
cout << "You have enough bones with " << numberofbones - comparableDrag << " left over, get to sacrafising!" << endl;
}
else {
cout << "You will need " << comparableDrag - numberofbones << " more bones" << endl;
}
}
if (BoneSelection == 'b' || BoneSelection == 'B') {
cout << endl << "With Big Bones you need a total of " << comparableBig << " Bones" << endl;
if (comparableBig < numberofbones) {
cout << "You have enough bones with " << numberofbones - comparableBig << " Left over, get to sacrafising!" << endl;
}
else {
cout << "You will need " << comparableBig - numberofbones << " more bones" << endl;
}
}
if (BoneSelection == 'c' || BoneSelection == 'C') {
cout << endl << "With BabyDragon Bones you will need " << comparableBaby << " Bones" << endl;
if (comparableBaby < numberofbones) {
cout << "You have enough bones with " << numberofbones - comparableBaby << " left over, get to sacrafising!" << endl;
}
else {
cout << "You will need " << comparableBaby - numberofbones << " more bones" << endl;
}
}
}
else if (Gildedaltar == 'n' || Gildedaltar == 'N') {
system("cls");
cout << "What bones will you be using: " << endl;
cout << "a) Dragon Bones " << endl;
cout << "b) Big Bones " << endl;
cout << "c) BabyDragon Bones " << endl;
cin >> BoneSelection;
if (BoneSelection == 'a' || BoneSelection == 'A') {
cout << endl << "With Dragon Bones, you will need " << comparableDragNoAltar << " Bones " << endl;
if (comparableDragNoAltar < numberofbones) {
cout << "You have enough bones with " << numberofbones - comparableDragNoAltar << " left over, get to sacrafising!" << endl;
}
else {
cout << "You will neeed " << comparableDragNoAltar - numberofbones << " More bones" << endl;
}
}
if (BoneSelection == 'b' || BoneSelection == 'B') {
cout << endl << "With Big Bones, you will need " << comparableBigNoAltar << " Bones" << endl;
if (comparableBigNoAltar < numberofbones) {
cout << "You have enough bones with " << numberofbones - comparableBigNoAltar << " Left over, get to sacrafising!" << endl;
}
else {
cout << "You will need " << comparableBigNoAltar - numberofbones << " More bones" << endl;
}
}
if (BoneSelection == 'c' || BoneSelection == 'c') {
cout << endl << "With BabyDragon Bones, you will need " << comparableBabyNoAltar << " Bones" << endl;
if (comparableBabyNoAltar < numberofbones) {
cout << "You have enough bones with " << numberofbones - comparableBabyNoAltar << " Left over, get to sacrafising!" << endl;
}
else {
cout << "You will need " << comparableBigNoAltar - numberofbones << " More Bones" << endl;
}
}
}
else {
goto prompt;
}
}
You can ignore most of the code, I know it probably looks really sloppy and there's probably much betters ways of handling most of the things in here. I just decided to make this out of boredom and figured it could be a good lesson to learn from for me. if you know of a way to help me I would be more than happy to hear the solution, if there's a way to get the program to ignore the commas completly that would be even better but alas I don't believe there's a way to do that.
P.S. please don't get too technical with me, I've only taken one course on this stuff :) Thanks in advance for the help.

You just need to remove the commas from the input string before trying to get an int from it. Better would be to remove any non-digit chars from the input, which you can do with isdigit(). Then call atoi() on it.
string& remove_nondigit(string& s) {
s.erase(remove_if(s.begin(), s.end(), [](const char& c) {
return !isdigit(c);
}), s.end());
return s;
}
yourF() {
string sBones;
cin >> sBones;
cout >> remove_nondigit(sBones);
// you'll want to use atoi() on sBones
}

Related

How do I go about fixing my calculator answers in my c++ program with a basic menu?

I have a basic menu program that gives the user different programs to choose from and run, when I run the simpleCalculator option and iput values and the operation of arithmetic the output is always the wrong answer but when I first programmed the calculator program without the menu and it being in its own function it would run just fine and give the the right answers, what exactly is going wrong here?
Ignore the third option in the menu since i haven't added code for the prime number checker program
double first_arg;
double second_arg;
string arithmeticOperation;
int numBottles = 99;
double simpleCalculator()
{
cout << "Enter first value: ";
cin >> first_arg;
cout << "Enter choice of arithmetic operation:\n* = multiplication\n/ = division\n+ = addition\n- = subtraction\n\n";
cin >> arithmeticOperation;
cout << "\nEnter second value: ";
cin >> second_arg;
if(arithmeticOperation == "*")
{
cout << "\nYour answer is " << first_arg * second_arg;
}
else if(arithmeticOperation == "/")
{
cout << "\nYour answer is " << first_arg / second_arg;
}
else if(arithmeticOperation == "+")
{
cout << "\nYour answer is " << first_arg + second_arg;
}
else if(arithmeticOperation == "-")
{
cout << "\nYour answer is " << first_arg - second_arg;
}
else
{
cout << "\nPlease enter a valid choice of an arithmetic operation\n";
}
}
string bottlesProgram()
{
while(true)
{
if (numBottles > 2)
{
cout << numBottles << " bottles of beer on the wall\n" << numBottles << " bottles of beer!\n" << "Take one down\nPass it around\n" << numBottles - 1 << " bottles of beer on the wall.";
cout << "\n\n";
}
else if(numBottles == 2)
{
cout << numBottles << " bottles of beer on the wall\n" << numBottles << " bottles of beer!\n" << "Take one down\nPass it around\n" << numBottles - 1 << " bottle of beer on the wall.";
cout << "\n\n";
}
else if(numBottles == 1)
{
cout << numBottles << " bottle of beer on the wall\n" << numBottles << " bottle of beer!\n" << "Take one down\nPass it around\n" << numBottles - 1 << " bottles of beer on the wall.";
cout << "\n\n";
}
else if(numBottles == 0)
{
cout << "No more bottles of beer on the wall,\nNo more bottles of beer.\nGo to the store and buy some more,\n" << "99 bottles of beer on the wall...";
cout << "\n\n";
}
else
{
break;
}
numBottles--;
}
}
int main()
{
int menuInput;
cout << " ***Programs Menu***\n" << "------------------------------------------\n" << "1. Run a simple Calculator\n" << "2. Run 99 bottles of beer on the wall song\n" << "3. Run prime number checker program\n" << "------------------------------------------\n";
cin >> menuInput;
if(menuInput == 1)
{
cout << simpleCalculator();
}
else if (menuInput == 2)
{
cout << bottlesProgram();
}
}
You seem to be confused about returning values from a function, and printing values in a function. These are not the same thing.
If you print the values in the function then the function should be void (i.e. nothing is returned) and the printing happens inside the function (obviously)
void simpleCalculator()
{
...
cout << "\nYour answer is " << first_arg * second_arg;
...
}
simpleCalculator(); // no cout
On the other hand if you return a value from the function then the function is not void and the printing happens outside the function
double simpleCalculator()
{
...
return first_arg * second_arg; // return not cout
...
}
cout << "\nYour answer is " << simpleCalculator();
Your code is doing half one version and half the other.

I am trying to polish my output using (setw) but if the value that i enter differ in range it does not work properly

I am trying to fix my output using setw(4).I have tried different a range of number between 1 to 10 but none get me the desired output.
void Students(int& size_public)
{
cout << "Input the number of information to be entered: ";
cin >> size_public;
cout << endl << endl;
// Reseting the screen
system("cls");
for (int i = 0; i < size_public; i++)
{
cout << "________________________Enter the following information for the data to be stored________________________\n" << endl;
cout << "Name: ";
cin >> employees[i].name_public;
cout << "Age: ";
cin >> employees[i].age_public;
cout << "ID.No: ";
cin >> employees[i].ID_No_publice;
cout << endl;
system("cls");
}
}
void Students(Employee employees[arraysize], int& size_public)
{
for (int i = 0; i < size_public; i++)
{
if (i == 0)
{
cout << setw(10) << "Name\t" << "Age\t" << "ID.No" << endl << endl;
}
cout << setw(10) << employees[i].name_public << '\t'
<< employees[i].age_public << '\t'
<< employees[i].ID_No_publice << endl;
}
}
};
Later in the program it is called
if (selection == 2)
{
student.Students(size);
cout << "1. Leave\n";
cout << "2. Showinformation\n";
cout << "\n________________________________________________\n";
cout << "Enter your choice: ";
cin >> choice;
cout << "\n________________________________________________\n";
if (choice == 1)
{
cout << endl;
}
else if (choice == 2)
{
student.Students(student.employees, size);
}
else if (choice != 1 && choice != 2)
{
cout << "choice is not found\n";
}
}
This is what I am talking about
Name Age ID.No
fge 33 345674
sdfgfd 34 23
dfghjkjhg 354 54345
Space behind the names is what I am trying to avoid
This is the output i receive when i use setw(10)
and this is what happen when the range of input changes
Name Age ID.No
afjghbslkk;jfl 2 3
fg 3 5.67654e+06
3 34543 543
if you look at fg in name it has a space behind it and I am trying to avoid it
My desired output is something like
Name age ID.No
dfghsgffgdf 44553 4564564
ajkghjkgh 444 465454
ff 4 46
I do not know if it is possible but if I am missing any thing just let me know and i will update the code.
Example
if (i == 0)
cout << left << setw(10) << "Name" << setw(10) << "Age" << setw(10) << "ID.No" << endl << endl;
cout << left << setw(10) << employees[i].name_public
<< setw(10) << employees[i].age_public
<< setw(10) << employees[i].ID_No_publice << endl;
See if this is what you need.

Searching for an Integer in an Output File C++

I'm currently writing a menu driven program in C++ and I'm having a little difficulty searching for a certain int in an Output file. My function looks like this.
int studentId;
int searchId;
double examGrade1, examGrade2, examGrade3;
ifstream readGrades;
do
{
cout << "Enter the student ID: ";
cin >> searchId;
if (searchId < 0 || searchId > 9999) {
cout << "Your student ID must be in between 0 and 9999! Try again...\n";
}
} while (searchId < 0 || searchId > 9999);
readGrades.open("grades.txt");
if (readGrades)
{
system("cls");
while (readGrades >> studentId >> examGrade1 >> examGrade2 >> examGrade3)
{
if (searchId == studentId)
{
cout << left
<< "Student ID\t" << "Exam 1\t" << "Exam 2\t" << "Exam 3\t" << endl;
cout << "======================================" << endl;
cout << left << setw(4) << studentId << "\t\t"
<< fixed << setprecision(2)
<< left << setw(5) << examGrade1 << "\t"
<< left << setw(5) << examGrade2 << "\t"
<< left << setw(5) << examGrade3 << endl;
system("pause");
break;
}
else
cout << "Entered ID not found";
}
}
else
{
cout << "Error opening file!\n";
}
cout << endl; }
Now the problem is the else statement. I am supposed to prompt to the user that a certain ID doesn't exist. But I don't know how to make the else statement only run once in the while statement. Every time I search a non-existing ID, it will say "Entered ID not found" for however many times it reads the inputs.
So the results look something like this.
No ID Found
At the same time, if I enter an ID that does exist but it's third in the file, it will look something like this. ID Found
I know logically what is happening, it keeps running the while loop for however many times. But I don't know how to deal with the problem. Any help to lead me to the right direction would be helpful. I'm new to coding/C++ and not too familiar with searching for something inside a file. Thank you!
The else block is in the wrong place. You need to update your logic such that you print that message only if the student ID is not found after going through the entire file. Which means, it has be outside the while loop.
if (readGrades)
{
bool found = false;
while (readGrades >> studentId >> examGrade1 >> examGrade2 >> examGrade3)
{
if (searchId == studentId)
{
cout << left
<< "Student ID\t" << "Exam 1\t" << "Exam 2\t" << "Exam 3\t" << endl;
cout << "======================================" << endl;
cout << left << setw(4) << studentId << "\t\t"
<< fixed << setprecision(2)
<< left << setw(5) << examGrade1 << "\t"
<< left << setw(5) << examGrade2 << "\t"
<< left << setw(5) << examGrade3 << endl;
found = true;
break;
}
}
if ( !found )
{
cout << "Entered ID not found";
}
}

Add a countdown timer to a math program quiz

I am trying to add a countdown timer to this program. I would like the timer to start when the first math fact question is asked and upon expiration i want the program to give the grade. What's the code to do this in c++ if possible?
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cstring>
using namespace std;
int main(int args, char* argv[])
{
int i;
int result;
int solution;
char fact;
bool done = false;
int correct = 0;
int count = 0;
do {
try {
cout << "Enter (m)ultiplication or "
<< "(a)ddition." << endl; /*or (s)ubstraction. */
cin >> fact;
while (!cin)
throw fact;
if (fact != 'A')
if (fact != 'a')
if (fact != 'M')
if (fact != 'm')
while (!cin)
throw fact;
cout << "Now, enter the number of the fact that
you would like to do." << endl;
cin >> i;
int wrong = 0;
int score = 0;
int j = 0;
while (!cin)
throw i;
switch (fact) {
case 'm':
case 'M':
while (j < 13) {
cout << "What's " << i << " x " << j << "?" << endl;
cin >> result;
while (!cin)
throw result;
solution = i * j;
if (result == solution) {
cout << "Great Job! That is the correct answer for the problem "
<< i << " x " << j << "." << endl;
cout << endl;
cout << endl;
cout << endl;
score++;
j++;
cout << endl;
}
if (result != solution) {
cout << "Oh no! " << result << " is NOT the correct answer for "
<< i << " x " << j << "." << endl;
wrong = wrong + 1;
count++;
}
if (count == 3) {
cout << "The correct answer is " << i * j << "." << endl;
j++;
wrong = wrong - 3;
count = 0;
}
if (count == 1) {
cout << endl;
count--;
wrong = wrong - 1;
}
if (count == 2) {
cout << endl;
count--;
wrong = wrong - 2;
}
}
case 'a':
case 'A':
while (j < 13) {
cout << "What's " << i << " + " << j << "?" << endl;
cin >> result;
while (!cin)
throw result;
solution = i + j;
if (result == solution) {
cout << "Great Job! That is the correct answer for the problem "
<< i << " + " << j << "." << endl;
cout << endl;
cout << endl;
cout << endl;
score++;
j++;
cout << endl;
}
if (result != solution) {
cout << "Oh no! " << result << " is NOT the correct answer for "
<< i << " + " << j << "." << endl;
wrong = wrong + 1;
count++;
}
if (count == 3) {
cout << "The correct answer is " << i + j << "." << endl;
j++;
wrong = wrong - 3;
count = 0;
}
if (count == 1) {
cout << endl;
count--;
wrong = wrong - 1;
}
if (count == 2) {
cout << endl;
count--;
wrong = wrong - 2;
}
}
if (j == 13) {
system("pause");
correct = score - wrong;
score = (correct * 100) / 13;
}
if (score >= 80) {
cout << "Excellent!!!!!" << endl;
cout << "You scored " << score << "%." << endl;
cout << "You got " << correct << " out of 13 correct." << endl;
cout << "Keep up the good work." << endl;
} else if (score >= 70) {
cout << "Congratulations!!!!!" << endl
cout << "You scored " << score << "%." << endl;
cout << "You got " << correct << " out of 13 correct." << endl;
cout << "Let's see if we can score even higher next time." << endl;
} else {
cout << "You scored below 70 which means that you may need some"
<< " more practice." << endl;
cout << "You scored " << score << "%." << endl;
cout << "You got " << correct << " out of 13 correct." << endl;
cout << "You might want to try the " << i << " facts again."
<< " Goodluck!!!!!" << endl;
}
}
} catch (char fact) {
cout << "Invalid input. You can only enter (m)ultiplication or"
<< " (a)ddition. Please try again." << endl;
cin.clear();
cin.ignore(100, '\n');
} catch (int i) {
cout << "Invalid input0. You can only enter a
number here. Please try again." << endl;
cin.clear();
cin.ignore(100, '\n');
} catch (...) {
cout << "Invalid input2. You can only enter a number here.
Please try again." << endl;
cin.clear();
cin.ignore(100, '\n');
}
} while (!done);
return 0;
}
The task is quite hard, but if you dare trying, I suggest doing it in two steps:
Implement inaccurate solution: timer expiration is checked between queries to user.
If there is some time left, next question is asked, otherwise statistics is shown. So program always waits for user input on the last question despite timer has run out. Not what exactly quizzes look like, but good move to start with.
Method: before starting quiz save current time, before each question take delta between saved time and current one and compare with time limit. Example with chrono (starting from C++11), example with oldschool clock
Add middle-question interruption
This part requires function, which will wait for user input not longer, than specified amount of time. So instead of using std::cin() you'll need to calculate amount of time left (time limit minus delta between cur time and start time) and call some sort of cin_with_timeout(time_left).
The hardest thing is implementing cin_with_timeout(), which requires solid knowledge of multithreading and thread synchronization. Great inspiration can be found here, but it is direction to start thinking rather than complete solution.

C++ Hangman Game, how to make "right" letter stick

I am trying to do a hangman project, but my code isn't working. Whenever I put in the proper letter, the code tells me it is wrong (even though it is right). Not really sure why - the code worked at some point but I changed some things and now I don't know why it doesn't work. So it is probably a simple fix, but I am just not seeing it.
Any help would be very appreciated!
#include <iostream>
using namespace std;
int letterFill (char, string, string&);
int main()
{
string name;
int maxAttempts = 5;
int wrongGuesses;
char letter;
srand(time(0));
const string wordList[15] = { "hanukkah", "sparklers", "mistletoe", "menorah", "presents", "reindeer",
"kwanzaa", "snowman", "eggnog", "celebration", "yuletide", "resolution", "nutcracker", "ornaments", "gingerbread" };
string correctWord = wordList[rand() % 15];
string unknown(correctWord.length(),'*');
cout << correctWord << endl;
cout << "Welcome to a fun game of winter holiday hangman! What is your name? " << endl;
cin >> name;
cout << name <<", there are some simple things you should know about this game before you start playing!" << endl;
cout << "You will be trying to guess a randomly selected word by typing in ONE letter at a time " << endl;
cout << "You will have " << maxAttempts << " tries before losing the game " << endl;
cout << "And remember, all of the words are winter holiday related. Good luck " << name <<"!" << endl;
cout << "*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*" <<endl;
while (wrongGuesses == 0)
{
cout << "Guess a letter" << cout;
cin >> letter;
if (letterFill(letter, correctWord, unknown)==0)
{
cout << endl << "That letter is not in this word! Try again " << endl;
wrongGuesses = wrongGuesses + 1;
}
else
{
cout << endl << "You found a letter! Keep up the good work! " << endl;
}
if (correctWord==unknown)
{
cout << correctWord << endl;
cout << "Congratulations! You guessed the correct word!" << endl;
}
}
while (wrongGuesses == 1)
{
cout << "You have 4 guesses left " << endl;
cout << "Guess a letter " << cout;
cin >> letter;
if (letterFill(letter, correctWord, unknown)==0)
{
cout << endl << "That letter is not in this word! Try again " << endl;
wrongGuesses = wrongGuesses + 1;
}
else
{
cout << endl << "You found a letter! Keep up the good work! " << endl;
}
if (correctWord==unknown)
{
cout << correctWord << endl;
cout << "Congratulations! You guessed the correct word!" << endl;
}
}
while (wrongGuesses == 2)
{
cout << "You have 3 guesses left " << endl;
cout << "Guess a letter " << cout;
cin >> letter;
if (letterFill(letter, correctWord, unknown)==0)
{
cout << endl << "That letter is not in this word! Try again " << endl;
wrongGuesses = wrongGuesses + 1;
}
else
{
cout << endl << "You found a letter! Keep up the good work! " << endl;
}
if (correctWord==unknown)
{
cout << correctWord << endl;
cout << "Congratulations! You guessed the correct word!" << endl;
}
}
while (wrongGuesses == 3)
{
cout << "You have 2 guesses left " << endl;
cout << "Guess a letter " << cout;
cin >> letter;
if (letterFill(letter, correctWord, unknown)==0)
{
cout << endl << "That letter is not in this word! Try again " << endl;
wrongGuesses = wrongGuesses + 1;
}
else
{
cout << endl << "You found a letter! Keep up the good work! " << endl;
}
if (correctWord==unknown)
{
cout << correctWord << endl;
cout << "Congratulations! You guessed the correct word!" << endl;
}
}
while (wrongGuesses == 4)
{
cout << "You have 1 guess left " << endl;
cout << "Guess a letter " << cout;
cin >> letter;
if (letterFill(letter, correctWord, unknown)==0)
{
cout << endl << "That letter is not in this word! Try again " << endl;
wrongGuesses = wrongGuesses + 1;
}
else
{
cout << endl << "You found a letter! Keep up the good work! " << endl;
}
if (correctWord==unknown)
{
cout << correctWord << endl;
cout << "Congratulations! You guessed the correct word!" << endl;
}
}
while (wrongGuesses == 5)
{
cout << "Sorry " << name << " you have made 5 wrong guesses!" << endl;
cout << "Game over. Click any key to exit. Play again soon :) " << endl;
if (letterFill(letter, correctWord, unknown)==0)
{
cout << endl << "That letter is not in this word! Try again " << endl;
wrongGuesses = wrongGuesses + 1;
}
else
{
cout << endl << "You found a letter! Keep up the good work! " << endl;
}
if (correctWord==unknown)
{
cout << correctWord << endl;
cout << "Congratulations! You guessed the correct word!" << endl;
}
}
system("pause");
return 0;
}
int letterFill (char guessLetter, string mysteryWord, string& guessWord)
{
int x;
int matches=0;
int lengthWord=mysteryWord.length();
for (x = 0; x< lengthWord; x++)
{
if (guessLetter == mysteryWord[x])
return 0;
if (guessLetter == mysteryWord[x])
{
guessWord[x] = guessLetter;
matches++;
}
}
return matches;
}
You aren't updating the string guessWord in your int letterFill() function. As soon as you see a letter that matches you return without entering that second if statement.
I assume what you want is only to return after fully updating the guessWord, based on that what you want to do is iterate through the string, updating guessWord as you find matches and after your loop do a check
if(matches == 0) return 0;
else return matches;