C++ Guess Number game crashing on other computers and infinite loop fix - c++

// Guess my number
// My first text based game
// Created by USDlades
// http://www.USDgamedev.zxq.net
#include <cstdlib>
#include <ctime>
#include <string>
#include <iostream>
using namespace std;
int main()
{
srand(static_cast<unsigned int>(time(0))); // seed the random number generator
int guess;
int secret = rand() % 100 + 1; // Generates a Random number between 1 and 100
int tries =0;
cout << "I am thinking of a number between 1 and 100, Can you figure it out?\n";
do
{
cout << "Enter a number between 1 and 100: ";
cin >> guess;
cout << endl;
tries++;
if (guess > secret)
{
cout << "Too High!\n\n ";
}
else if (guess < secret)
{
cout << "Too Low!\n\n ";
}
else
{
cout << "Congrats! you figured out the magic number in " <<
tries << " tries!\n";
}
} while (guess != secret);
cin.ignore();
cin.get();
return 0;
}
My code runs fine on my computer but when a friend of mine tries to run it, The program crashes. Does this have to do with my coding? Also I found that when I enter a letter for a guess, my game goes into an infinite loop. How can I go about fixing this issue?

The "crash" is probably related to missing runtime libraries, which would result in an error message similar to
The application failed to initialize
properly [...]
...requiring your friend to install the missing runtime libraries, e.g.
http://www.microsoft.com/downloads/en/details.aspx?familyid=a5c84275-3b97-4ab7-a40d-3802b2af5fc2&displaylang=en
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=a7b7a05e-6de6-4d3a-a423-37bf0912db84
Choose the version that matches whatever version of Visual Studio you used to develop your application, as well as the target platform.
As for your application entering an infinite loop: after entering a letter, the input stream will be in an error state and thus unusable. Code similar to the following will prevent that:
#include <limits>
...
...
...
std::cout << "Enter a number between 1 and 100: ";
std::cin >> guess;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Basically, the code clears the error bits and removes any remaining input from the input buffer, leaving the stream in an usable state again.

Related

For Loops (C++)

Assignment:
The program should ask the user to enter a positive number and display all numbers from 1 to the input value. If the number is not positive, an error message should show up asking the user to re - enter the number.
My specific problem:
For my program, if the user enters an incorrect number and then re - enters a positive number, it does not display all the numbers from 1 to the input value. The program just ends.
#include <iostream>
using namespace std;
int main()
{
int userChoice;
int i = 1;
cout << "Enter a positive integer" << endl;
cin >> userChoice;
if (userChoice > 0)
{
for (i = 1; i <= userChoice; i++)
{
cout << "Loop 1:" << endl;
cout << i << endl;
}
}
else if (userChoice < 0)
cout << "Please re - enter" << endl;
cin >> userChoice;
system("pause");
return 0;
}
You need some sort of loop at the top of your program, that keeps asking for input until the user provides something valid. It looks like a homework assignment, so I will provide pseudo-code, not something exact:
std::cout << "Enter a number:\n";
std::cin >> choice;
while (choice wasn't valid) { // 1
tell the user something went wrong // 2
ask again for input in basically the same way as above // 3
}
// after this, go ahead with your for loop
It is actually possible to avoid the duplication here for step 3, but I worry that might be a little confusing for you, so one duplicated line really isn't such a big problem.
As an aside, you may wish to reconsider your use of what are often considered bad practices: using namespace std; and endl. (Disclaimer - these are opinions, not hard facts).

Print out last line and then run program again Y/N

I am stuck on this random guessing game for school.
I have added the code that needed to be added, but the console keeps closing without returning the last strings.
I would also like to learn how to make the program run again with clicking Y to run again.
I am still learning C++, so any help would be appreciated.
Code:
// GuessingGameApp.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>//added to run string
#include <locale>//added toupper run again
using namespace std;
int main()
{
//Seed the random number generator
srand(time(0));
int selectedNumber = rand() % 20 + 1; int numberOfTries = 0;
int inputtedGuess;
std::cout << "Guess My Number Game\n\n";
//Ask the user for a value until the correct number is entered
do {
std::cout << "Enter a guess between 1 and 20:";
std::cin >> inputtedGuess;
++numberOfTries;
if (inputtedGuess > 20 || inputtedGuess < 1) {
cout << "Your guess is out of range.\n\n";
}
else if (inputtedGuess > selectedNumber) {
cout << "Too high!\n\n";
}
else if (inputtedGuess < selectedNumber) {
cout << "Too low!\n\n";
}
}
while (inputtedGuess != selectedNumber);
//Congratulate the user and end the program
std::cout << "\nCongratulations! You solved it in " << numberOfTries << " tries!\n" << std::endl;
//fix problem with console closing and (add "play again" option), so I can
//learn
//printf; did not work... Break did not work..
//
return 0;
}
I was able to get the console to stay open by putting a break at line 33, but I want to learn how to do this correctly so I deleted the break.
The last line of your output should actually be printed. The reason why the last line "is not printed" is probably that your IDE closes the console before you can see the final output (though it should be there). Many IDEs allow to make the console visible after program termination. BTW: Note that when pasting the code you probably lost a << before std::endl in std::cout << "\nCongratulations! You solved it in " << numberOfTries << " tries!\n" std::endl; But this has actually to be a copy-paste problem, because your program would not have compiled otherwise.
Anyway, by providing a "Try again?"-logic, your program does not terminate and the problem is solved.
I'd suggest to provide a separate function performing the guess, which is then called in a do-while loop with the "Try again="-question.
void guess() {
// your code (except srand) goes here...
}
int main() {
srand(time(0)); //Seed the random number generator only once
char doAgain;
do {
guess();
cout << "Try again (Y/N)?";
cin >> doAgain;
}
while (toupper(doAgain)=='Y');
return 0;
}
As people suggested, you can add another do-while loop to repeat the game.
int choice = 0;
do {
// first part of code..
do {
// inner do-while
} while (inputtedGuess != selectedNumber);
std::cout << "\nCongratulations! You solved it in " << numberOfTries << " tries!\n" std::endl;
cout << "\nWould you like to play again?\n\n";
cout << "1 - Yes\n";
cout << "2 - No\n\n";
cout << "Choice: ";
cin >> choice;
} while(choice == 1);

C++: " multiple definition of 'mainCRTStartup' " error etc

So I was doing some beginner challenges and wanted to modify my code, this was what i did first.
#include <iostream>
#include <stdlib.h>
#include <time.h>
int random;
int guess;
int num_guess = 1;
int main(){
srand(time(NULL));
random = rand() % 100 + 1;
std::cout << "Try to guess my number between 1 and 100." << std::endl;
std::cin >> guess;
while(guess > random){
std::cout << "Sorry too high but i'll give you another try." << std::endl;
std::cin >> guess;
num_guess += 1;
}
while(guess < random){
std::cout << "Sorry too low but i'll give you another try." << std::endl;
std::cin >> guess;
num_guess += 1;
}
if(guess = random){
std::cout << "WOW! Congratulations you actually got it, you did use " << num_guess << " tries tho." << std::endl;
}
return(0);
}
It is supposed to generate a random number between 1 and 100, and then you guess what number it is. But then I copied this code over to another file under the same project because im doing this in school so I wanted all the different versions of my code for documentary purposes. But when I started writing the new code where the program is supposed to guess a number you give it between 1 and 100.
#include <iostream>
#include <stdlib.h>
#include <time.h>
int number;
int guess = 100;
int num_guess = 1;
int main(){
std::cout << "Please enter any number between 1 and 100" << std::endl;
std::cin >> number;
if(number > 100 && number < 1){
std::cout << "Enter a valid number" << std::endl;
std::cin >> number;
}
srand(time(NULL));
guess = rand() % guess + 1;
return(0);
}
I erased the old code from main.cpp and wrote this instead, but when I tried to run it i got these error messages:
multiple definition of `mainCRTStartup'
multiple definition of `WinMainCRTStartup'
multiple definition of `atexit'
multiple definition of `_onexit'
multiple definition of `__gcc_register_frame'
multiple definition of `__gcc_deregister_frame'
undefined reference to `_Jv_RegisterClasses'|
Guess you didn't exclude your old file from the project. In this case linker meets two main functions and doesn't know what to use. Possible ways to solve it:
exclude unused file from the project;
comment out old version;
use conditional compilation:
#ifdef OLD_VER
// main1
...
#else
// main2
...
#endif
create a new project;
use version control systems.
First 3 methods are not recommended for a long use. The last one is a good point (the best point, I think) but it can require elementary VCSs learning.

how to allow multiple inputs in case of an incorrect data type entry in cpp?

I have a program which generates random number and asks user to keep guessing it until he/she gets it right. I want it to keep accepting new values even if i incorrectly enter any other data type by handling the error cases.
My problem is that when i am trying to run the below program, as soon i input a character and hit enter, it goes into an infinite loop. I tried using cin.ignore() and cin.clear() but that just makes the program stop after the first entry.
Can anyone please help me understand what is going on and how to achieve the desired output? Thanks in advance.
#include <iostream>
#include <cstdlib>
#include <time.h>
using namespace std;
int main()
{
int secret_num, guess;
srand(time(NULL));
secret_num=rand() % 101 + 0;
cout<<"Enter your guess between 0 and 100: ";
do
{
if(!(cin>>guess))
{
cout<<" The entered value is not an integer"<<endl;
}
else if( isnumber(guess))
{
if(guess>secret_num)
cout<<"Too high";
else if(guess<secret_num)
cout<<"too low";
cout<<endl;
}
}
while(secret_num!=guess);
if((guess==secret_num)| (isnumber(guess)))
{
cout<<"yes the correct number is "<<secret_num<<endl;
}
return 0;
}
Edit: Here is a screenshot of what the output looks like with cin.clear() and cin.ignore(1000,'\n') in my code, when i enter a number after entering character twice.
if (!(cin >> guess))
{
cout << " The entered value is not an integer" << endl;
cin.clear(); // clear must go before ignore
// Otherwise ignore will fail (because the stream is still in a bad state)
cin.ignore(std::numeric_limits<int>::max(), '\n');
}
By default cin.ignore will ignore a single character. If they type more than 1 char, it won't be enough, that's why I've modified it a bit.
if ((guess == secret_num) | (isnumber(guess)))
| is a bitwise operator [OR]
|| is the logical operator [OR]
But I think what you actually want is && (AND)
if ((guess == secret_num) && (isnumber(guess)))
There're several problems.
You should use cin.clear() and cin.ignore() as #José suggested.
What's isnumber()? I guess it's returning false so no hint message (i.e. "Too high" and "too low") is printed out, looks like it stops although it's just waiting the next input. And isnumber() doesn't make sense to me. guess has been declared as an int, it has to be a number, doesn't it?
if((guess==secret_num)| (isnumber(guess))) is unnecessary here. The loop won't end until the user input the correct number, this condition should have been statisfied.
You can use clear and flush
if(!(cin>>guess))
{
cout<<" The entered value is not an integer"<<endl;
cin.clear();
fflush(stdin);
}
This works if you are reading from console. Otherwise you can go with #José answer.
I would change the logic inside your loop as there are some useless tests. This works for me:
#include <iostream>
#include <limits>
#include <cstdlib> // You may take a look at <random> and <chrono>
#include <time.h>
using std::cout;
using std::cin;
int main() {
srand(time(NULL));
int secret_num = rand() % 101;
cout << secret_num << '\n';
cout << "Enter your guess between 0 and 100:\n";
int guess = -1;
do {
cin >> guess;
if ( cin.eof() )
break;
if ( cin.fail() ) {
cout << "The entered value is not an integer, please retry.\n";
// clear the error flag
cin.clear();
// ignore the rest of the line
cin.ignore(std::numeric_limits<int>::max(),'\n');
// clear the value of the variable
guess = -1;
continue;
}
// now we know that guess is a number
if ( guess > secret_num )
cout << "Too high\n";
else if ( guess < secret_num )
cout << "Too low\n";
else {
cout << "Yes the correct number is " << secret_num << std::endl;
break;
}
} while ( true );
return 0;
}

Guess the number - Infinite loop when bad read

So I am making this Guess the number game in c++ that looks like this:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
srand(time(0));
int secretNumber = rand() % 100 + 1; //Generate "Random number"
int nbrOfGuesses = 0;
int userInput;
cout<<"\t************************************"<<endl;
cout<<"\t* *"<<endl;
cout<<"\t* Guess the number! *"<<endl;
cout<<"\t* *"<<endl;
cout<<"\t************************************"<<endl;
cout<<endl;
cout << "Try to find the secret int number: " << endl;
//While input is good
while(cin.good())
{
//Do this
do {
cin>>userInput;
nbrOfGuesses++;
if (userInput>secretNumber)
cout << "Smaller!\n";
else if(userInput<secretNumber)
cout << "Bigger!\n"; // <-- Infinite loop here when you enter something other than an integer
else //Also using this as a backup of (cin.good())
cout << "Something went wrong with the read";
break;
} while(userInput!=secretNumber);
cout << "\nCongratulations! You got it in " << nbrOfGuesses << " guesses\n";
}
system("pause");
return 0;
}
*Sorry if the code is note very elegant
As you can see, the code works great until you enter a random caracter like '&' or 'j' or anything else that isn't an integer...Then it loops at cout<<"Bigger!";
So my question is: What is causing this?
Check this post, it is about the same problem. To summarize:
cin>>userInput;
if (cin.fail()) {
cout<<"Invalid Entry, please try again."<<endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
Thanks ildjarn for pointing the missing ignore statement, I missed that part even though its clearly mentioned in the post I linked to!!
See this FAQ: How can I get std::cin to skip invalid input characters?
cin>>userInput;
If it cannot read an integet, the bad bit is set for the cin stream.
You should check and clear afterwords.
if ( cin.fail() )
{
cin.clear();
try again
}