I need to do some error handling in c++ that corrects user input if it's a letter or a string. I need to use .at(), .length(), and atoi to handle this. I'm not sure how/where to implement those is the problem.
#include <iostream>
#include <stdlib.h>
#include <string>
#include <time.h>
using namespace std;
int main() {
srand(time(0));
int number;
number = rand() % 50 + 1;
int guess;
int x;
for (x = 5; x > 0; x--) {
cout << "Guess my number, it's between 0-50. You have 5 guesses: ";
cin >> guess;
if (guess < number){
cout << "Your guess was too low" << endl;
}
else if (guess > number){
cout << "You guess was too high" << endl;
}
else {
cout << "You're exactly right!" << endl;
break;
}
} while (guess != number){
break;
}
return 0;
}
The best approach to input validation is to write a function that reads into a std::string, checks whatever is needed, and only returns a value when it passes the tests:
int get_value() {
std::string input;
int value = -1;
while (value < 0) {
std::cout << "Gimme a value: ";
std::getline(std::cin, input);
try {
value = std::stoi(input);
} catch(...) {
value = -1;
}
}
return value;
}
Related
I am trying to write a program that checks if a phrase is a palindrome or not, and in case nothing is entered or just whitespace, it should print out "empty".
At first, the user should type in the number of phrases that they are going to enter (e.g. 3), and then the phrases that are to be checked.
It works just fine, but when my first input is empty, it prints out "empty" again and again without asking for another phrase.
#include <iostream>
#include <string>
#include <iomanip>
#include <math.h>
using namespace std;
int main() {
int N;
int isPalindromeCounter=0;
int counter = 0;
string inputString;
cin >> N;
cout << "\n";
while (counter<N){
counter++;
cin.ignore(100, '\n');
cin >> noskipws >> inputString;
if (inputString.length()==0){
cout <<"empty\n";
continue;
}
int left = 0;
int right = inputString.length()-1;
if (inputString.length()>20){
cout <<"error\n";
continue;
}
bool isPalindrome = true;
while (left<right){
if (inputString[left] != inputString[right]){
isPalindrome = false;
cout << "no\n";
break;
}
left++;
right--;
}
if (isPalindrome){
cout << "yes\n";
isPalindromeCounter++;
}
}
double percentage = double(isPalindromeCounter)/double(counter)*100;
if (trunc(percentage) != percentage){
cout << setprecision(5) << percentage;
}
else {cout << percentage << ".000" ;}
return 0;
}
What am I doing wrong ?
I expected that it should print "empty" once, and then ask for another input, but it prints "empty" for all the inputs.
When the user inputs 'Y' to try again, the game runs but only gives the user 1 try instead of 3 tries. Program works fine the first time it runs with 3 tries. I'm guessing something is wrong with my loop that it does not reset the number of tries? Let me know if there's any other way I could write my code to make it cleaner/better. Thanks a bunch.
#include <iostream>
#include <cstdlib>
#include <time.h>
using namespace std;
int guessNum;
int randomNum;
int Tries = 0;
int startGame()
{
cout << "Number: ";
cin >> guessNum;
return guessNum, Tries;
}
int main(int a, int b)
{
while (true) {
a = guessNum;
b = Tries;
char ans;
// Random number
srand(time(NULL));
randomNum = rand() % 20 + 1;
// Introduction
cout << "Guess a number between 1 to 20. You have three attempts." << endl;
do
{
startGame();
if (guessNum < randomNum)
{
cout << "Wrong! It is too low." << endl;
}
else if (guessNum > randomNum)
{
cout << "Wrong! It is too high." << endl;
}
Tries++;
}
while (guessNum != randomNum && Tries < 3);
if (guessNum != randomNum) // Wrong answer & run out of tries
{
cout << "Oops.. All attempts used. The answer is " << randomNum << endl;
}
else if (guessNum == randomNum) // User guessed correct number
{
cout << "Yes! You are correct!" << endl;
}
cout << "Try again?";
cin >> ans;
cin.ignore();
if (ans == 'N')
{
cout << "Thanks for playing!";
break;
}
}
}
EDITED V1
#include <iostream>
#include <ctime>
using namespace std;
int guessNum;
int startGame()
{
cout << "Number: ";
cin >> guessNum;
return guessNum;
}
int main()
{
while (true) {
int randomNum;
int Tries = 0;
char ans;
// Random number
srand(time(NULL));
randomNum = rand() % 20 + 1;
// Introduction
cout << endl << "Guess a number between 1 to 20. You have three attempts." << endl;
do
{
startGame();
if (guessNum < randomNum)
{
cout << "Wrong! It is too low." << endl;
}
else if (guessNum > randomNum)
{
cout << "Wrong! It is too high." << endl;
}
Tries++;
}
while (guessNum != randomNum && Tries < 3);
if (guessNum != randomNum) // Wrong answer & run out of tries
{
cout << "Oops.. All attempts used. The answer is " << randomNum << endl;
}
else if (guessNum == randomNum) // User guessed correct number
{
cout << "Yes! You are correct!" << endl;
}
cout << "Try again? Y/N: ";
cin >> ans;
cin.ignore();
ans = toupper(ans);
if (ans == 'N')
{
cout << endl << "Thanks for playing!";
break;
}
else
{
Tries = 0;
}
}
}
Actually, your program has several defects.
Firstly, If you wonder why the game behaves unexpected way after the first one, You did not set back the Tries to 0 after playing the game.
And, int startgame() should return only one variable. You are trying to return guessnum and Tries at the same time. The only reason the first game is running as expected is that you are using global variables, which is also considered as a bad practice(Some company may fire you if you use it without any good reason).
Furthermore, you are getting two int function arguments from main call, which is not valid. (main function signature should be int main(void) or int main(int argc, char* argv[])). I am surprised that the compiler did not catch this error.
And the variables (int a, int b) are actually not used. When you find unused variables, it is usually a good practice to remove them for maintainability.
So int Tries = 0; is a global variable. It's set before main().
You basically have
int Tries = 0;
main()
{
while (true) {
do
{
Tries++;
} while(Tries < 3);
}
}
Do you see that for each iteration in while, the value of Tries from the previous iteration is used? You would need to reset it before iterating again.
But there is no reason to have "Tries" as a global variable since you only need to know about it in the while(true)-loop. This is generally the case for a variable - put it to the closest scope possible:
main()
{
while (true) {
int Tries = 0;
do
{
Tries++;
} while(Tries < 3);
}
}
Now it's correctly reset between loops, and it is clear it is only needed for the loop logic.
Try to do the same for you other variables.
Try:
if (ans == 'N')
{
cout << "Thanks for playing!";
break;
}
else
{
Tries = 0;
}
Please disregard some of the undeclared variables. I do not really know what is wrong.
#include <iostream>
using namespace std;
int main()
{
int number{}, tries{}, ans{}, count{};
cout << "Enter an integer greater than 0: ";
cin >> number;
while (number > 0){
ans = number / 10;
++count;
if (ans == 0){
cout << "The number has " << count << "digits";
break;
}
}
return 0;
}
You're never actually changing number, so every iteration, you set ans to the same thing and run the same test.
As indicated by others, you are not updating the loop variable (number) anywhere inside the loop. Hence it is very likely to get in an infinite loop. Here is a sample updated code you can try out.
#include <iostream>
using namespace std;
int main()
{
int number{}, tries{}, ans{}, count{};
cout << "Enter an integer greater than 0: ";
cin >> number;
if (number<=0){
cout << "Incorrect input.";
}
else{
while (number>0){
number = number / 10;
count ++;
}
cout << "The number has " << count << " digits";
}
return 0;
}
'cause my program joins the previous input to my current input. I want to clear the previous input.
This is the code:
#include <cstdlib>
#include <iostream>
#include <math.h>
#include <conio.h>
using namespace std;
int main()
{
int ini=1,an=1,ans=1, f=1;
int bb=2;
int hypin;
string a="a.) Hyperfactorial";
string b="b.) Superfactorial";
string c="c.) Primorials";
string d="Exit";
string e="a. Yes";
string ff="b. No";
string letter;
string ysno;
start:
cout<<"\n"<<"Factorial"<<"\n"<<a<<"\n"<<b<<"\n"<<c<<endl;
cout<<"\n"<<"Enter letter:"<<endl;
cin>>letter;
if (letter=="a"){
cout<<"\n"<<"Enter number (maximum input:7) : "<<endl;
cin>>hypin;
if(hypin>=8){
cout<<"\n"<<"Invalid input!"<<endl;
}else{
while (hypin>1){
ini=ini*(pow(hypin,hypin));
hypin--;
}
cout<<"\n"<<"The hyperfactorial is: "<<ini<<endl;}
cout<<"\n"<<"Do you want to test another factorial?"<<"\n"<<e<<"\n"<<ff<<endl;
cout<<"\n"<<"Answer: ";
cin>>ysno;
if(ysno=="a"){
goto start;
}
if(ysno=="b"){
cout<<"\n"<<"Press any key to exit"<<"\n"<<endl;
getch();
return 0;
}
}
system("PAUSE");
return EXIT_SUCCESS;
}
Try clearing the cin buffer using
std::cin.ignore(INT_MAX);
Edit: You have to #include <limits.h> to use INT_MAX
You don't need to clear any thing. infact you have some little bug in your code that not set the answer every time.
I try to write a simple code for you:
bool validInput = false ,continueFlag = true;
string opr, ysno;
int a , b, ans = 0;
while(continueFlag)
{
cout << "Choose operation: a. Multiply b. Add \n Enter letter: " << endl;
cin >> opr;
if (opr != "a" && opr != "b")
{
cout << "Invalid input!"<<endl;
continue; // it returns to "while(continueFlag)" line
}
cout << "Enter First Number: ";
cin >> a;
cout << "Enter Second Number: ";
cin >> b;
if (opr == "a")
{
ans = a * b;
}
else
{
ans = a + b;
}
cout << "Answer is : "<< ans << endl;
do
{
cout << "Do you want to test another factorial? a. Yes b. No" << endl;
cin >> ysno;
if (opr != "a" && opr != "b")
{
cout << "Invalid input!"<<endl;
continue; // it returns to "do" line
}
validInput = true;
if (ysno == "b")
{
continueFlag = false;
}
}while(!validInput);
}
try this might be helpful
cout << "\033[2J\033[1;1H";
I used this code and compiled with g++ its working and linux platfrom(ubuntu)
#include <cstdlib>
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int ini=1,an=1,ans=1, f=1;
int bb=2;
int hypin;
string a="a.) Hyperfactorial";
string b="b.) Superfactorial";
string c="c.) Primorials";
string d="Exit";
string e="a. Yes";
string ff="b. No";
string letter;
string ysno;
start:
cout<<"\n"<<"Factorial"<<"\n"<<a<<"\n"<<b<<"\n"<<c<<endl;
cout<<"\n"<<"Enter letter:"<<endl;
cin>>letter;
if (letter=="a"){
cout<<"\n"<<"Enter number (maximum input:7) : "<<endl;
cin>>hypin;
cout << "\033[2J\033[1;1H";
if(hypin>=8){
cout<<"\n"<<"Invalid input!"<<endl;
}else{
while (hypin>1){
ini=ini*(pow(hypin,hypin));
hypin--;
}
cout<<"\n"<<"The hyperfactorial is: "<<ini<<endl;}
cout<<"\n"<<"Do you want to test another factorial?"<<"\n"<<e<<"\n"<<ff<<endl;
cout<<"\n"<<"Answer: ";
cin>>ysno;
if(ysno=="a"){
goto start;
}
if(ysno=="b"){
cout<<"\n"<<"Press any key to exit"<<"\n"<<endl;
return 0;
} }
system("PAUSE");
return EXIT_SUCCESS;
}
I'm having errors in my code below,
This is my code:
#include "stdafx.h"
#include <vector>
#include <iostream>
using namespace std;
int main(){
vector<int> numbers(0);
cout << "please enter you numbers :::\n''entering any characters but numbers is the end of entry''";
char ch;
int i = 0;
while (Isnumber(ch)){ //here is the error
do{
ch = getchar();
int newnumber = 0;
cout << "element(" << i << ") = ";
cin >> newnumber;
numbers.push_back(newnumber);
} while (ch>0 || ch < 9);
}
getchar();
}
two errors,
it says that identifier is unknown,
and
it says variable char is uninitialazed local variable,
change this while (Isnumber(ch)){ into do-while loop.
do{
.....
}while (Isnumber(ch))
The error is because ch is declared and it is used before initialized.
Also include #include <stdio.h>; for getchar();
Better do it in one loop:
do {
ch = getchar();
int newnumber = 0;
cout << "element(" << i << ") = ";
cin >> newnumber;
numbers.push_back(newnumber);
} while (Isnumber(ch)); // should probably be isdigit(ch)
And before asking similar questions read this first (or buy a book).
Well I solved it using cin functions as below,
#include "stdafx.h"
#include <vector>
#include <iostream>
using namespace std;
int main(){
vector<int> numbers(0);
cout << "please enter you numbers :::\n''entering any characters but numbers is the end of entry''\n";
//char ch;
int counter = 0;
do{
int newnumber = 0;
cout << "element(" << counter << ") = ";
counter++;
cin >> newnumber;
numbers.push_back(newnumber);
if (cin.fail()){
cout << "entered numbers are:\n";
for (vector<int>::iterator i = numbers.begin(); i != numbers.end(); i++)
{
cout << *i;
if (i != numbers.end()-1)cout << " - ";
}
}
} while (cin.good());
getchar();
}
I removed one while loop.
and used cin.fail and cin.good to avoid using IsNumber. And it worked.