Reputation: 21
This is the program:
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
int main(){
string strKingdom = "";
bool conquered_me;//see if was conquered, was going to use this on other program and true = game over.
int gold;
int food;
int citizens;
int soldiers;
cout << endl <<"Name of kingdom: ";
cin >> strKingdom;
cout << endl << "were you conquered (true/false): ";
cin >> conquered_me;
cout << endl << "How many gold do you have?:";
cin>>gold;
cout << endl << "How many food do you have?:";
cin >> food;
cout << endl << "How many citizens do you have?:";
cin >> citizens;
cout << endl << "How many soldiers do you have?:";
cin >> soldiers;
return 0;
}
The problem is that when I compile it the progam only lets me insert the first 2 variables and then it shows the rest of the questions (after compile):
Name of kingdom: steve
were you conquered (true/false): false
How many gold do you have?: How many food do you have?: How many citizens do you have?: How many soldiers do you have?:
Upvotes: 1
Views: 3210
Reputation: 2863
Entering string "true" to the bool
variable does not work. You should enter 1
or 0
. Your "true" cannot be "consumed", so it's left in the buffer. Next, you're trying to read int
value, so "true" also does not match. And so on... until the end of the program.
That's how I would do that:
#include <string>
#include <iostream>
#include <errno.h>
#include <stdlib.h>
using namespace std;
void askForString(string aPrompt, string &aValue) {
cout << aPrompt << " ";
cin >> aValue;
}
void askForBool(string aPrompt, bool &aValue) {
string tString;
while (1) {
cout << aPrompt << " ";
cin >> tString;
if (tString == "true") {
aValue = true;
break;
} else if (tString == "false") {
aValue = false;
break;
} else {
cout << "Repeat, please?" << endl;
}
}
}
void askForInt(string aPrompt, int &aValue) {
string tString;
char *endptr;
while (1) {
cout << aPrompt << " ";
cin >> tString;
errno = 0;
aValue = strtol(tString.c_str(), &endptr, 10);
if (errno || tString.c_str() == endptr || (endptr != NULL && *endptr != 0)) {
cout << "Repeat, please?" << endl;
} else {
break;
}
}
}
int main(void) {
string strKingdom;
bool conquered_me;
int gold;
int food;
int citizens;
int soldiers;
askForString("Name of kingdom:", strKingdom);
askForBool("were you conquered (true/false):", conquered_me);
askForInt("How many gold do you have?:", gold);
askForInt("How many food do you have?:", food);
askForInt("How many citizens do you have?:", citizens);
askForInt("How many soldiers do you have?:", soldiers);
cout << "Kingdom: " << strKingdom << endl;
cout << "Conquered: " << (conquered_me ? "true" : "false") << endl;
cout << "Gold: " << gold << endl;
cout << "Food: " << food << endl;
cout << "Citizens: " << citizens << endl;
cout << "Soldiers: " << soldiers << endl;
return 0;
}
Upvotes: 7
Reputation: 1473
You need to employ std::getline and std::string to read the various values. (You can then use functions like atoi to parse them.) Here is your code sample using the std::getline function.
#include <iostream>
#include <string>
#include <cstdlib>
int main(){
std::string strKingdom = "";
bool conquered_me;//see if was conquered, was going to use this on other program and true = game over.
int gold;
int food;
int citizens;
int soldiers;
std::string tString = ""; // Used to read and subsequently parse the string.
std::cout << std::endl <<"Name of kingdom: ";
std::getline(std::cin,strKingdom);
std::cout << std::endl << "were you conquered (true/false): ";
std::getline(std::cin,tString);
conquered_me = (tString == "true");
std::cout << std::endl << "How many gold do you have?:";
std::getline(std::cin,tString);
gold = std::atoi(tString.c_str());
std::cout << std::endl << "How many food do you have?:";
std::getline(std::cin,tString);
food = std::atoi(tString.c_str());
std::cout << std::endl << "How many citizens do you have?:";
std::getline(std::cin,tString);
citizens = std::atoi(tString.c_str());
std::cout << std::endl << "How many soldiers do you have?:";
std::getline(std::cin,tString);
soldiers = std::atoi(tString.c_str());
return 0;
}
Upvotes: 0
Reputation: 490108
For some reason (probably compatibility with older code) iostreams default to converting true
to 1
and false
to 0
during I/O.
That's only the default though--there's a manipulator named boolalpha
that will set the stream to use true
and false
(or localized equivalents) instead.
So, code like:
std::cout << 1 == 0; // produces `0`
std::cout << boolalpha << 1 == 0; // produces `false`
This also works for input, so you can change your code to something like this:
cin >> boolalpha >> conquered_me;
...and it should work as expected (and in: it should accept inputs of false
or true
, and produce values of false
and true
from them, and if it doesn't that's bug in the standard library).
Upvotes: 2
Reputation: 11181
This line:
cin >> conquered_me;
Should be like this:
cin >> boolalpha >> conquered_me;
Otherwise the input expects either a "0" or a "1".
By using boolalpha
your input can be "true" or "false.
Upvotes: 1
Reputation: 126193
None of your read commands check for error. ALL of them should be written as something like:
while (!(std::cin >> strKingdom)) {
std::cerr << 'Bad input' << std::endl;
std::cin.clear(); // clear the error
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // ignore the rest of the line
// output the same prompt again?
}
To make this easier, you might want to write a helper function:
template<typename T> void get_input(const char *prompt, T &result) {
std::cout << prompt << std::endl;
while (!(std::cin >> result)) {
std::cerr << 'Bad input' << std::endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << prompt << std::endl; } }
You can then specialize that for bool types to read true/false properly...
Upvotes: 1