How can I get my code to detect me hitting the enter key? I tried using cin.get() without any success. Also when the enter key is pressed, I'd like to change a boolean x from true to false.
Why doesn't this work?
if (cin.get() == '\n'){
x = false;
}
I'd like to end my loop (and thus and the program) when the enter key is pressed (see code below)
All code (simple rock, paper, scissors game):
#include <iostream>
#include <string>
#include <cstdlib> //random
#include <time.h> //pc time
using namespace std;
int main()
{
string rpsYou;
string rpsCom;
string winner;
bool status = true;
while (status){
cout << "Welcome to Rock, Scissors, Paper!\nYou'll have to compete against the computer."
" Please enter 'Rock', 'Paper' or 'Scissors' here: ";
cin >> rpsYou;
//Random number
srand (time(NULL));
int randomNum = rand() % 4; // -> (rand()%(max-min))+min;
//Computers guess
if (randomNum ==1){
rpsCom = "Rock";
}
else if (randomNum ==2){
rpsCom = "Paper";
}
else {
rpsCom = "Scissors";
}
//First letter to capital
rpsYou[0] = toupper(rpsYou[0]);
if (rpsYou == "Rock" || rpsYou == "Paper" || rpsYou == "Scissors"){
cout << "You: " << rpsYou << "\nComputer: " << rpsCom << "\n";
}
else {
cout << "ERROR: Please enter 'Rock', 'Paper' or 'Scissors'.";
}
if ( (rpsYou == "Rock" && rpsCom == "Rock") ||
(rpsYou == "Paper" && rpsCom == "Paper") ||
(rpsYou == "Scissors" && rpsCom == "Scissors") ){
cout << "Tie :|";
}
else if( (rpsYou =="Rock" && rpsCom =="Scissors") ||
(rpsYou =="Paper" && rpsCom =="Rock") ||
(rpsYou =="Scissors" && rpsCom =="Paper")){
cout << "Congratulations! You won! :)";
}
else{
cout << "Oh no! You lost! :(";
}
}
return 0;
}
You could do:
cout << "Hit enter to stop: ";
getline(cin, rpsYou);
if (input == "") {
status=false;
}
This is assuming there's nothing in the user input, (i.e: the user just simply presses enter)
You can't detect what key was pressed in standard C++. It's platform dependent. Here is a similar question that might help you.
Sounds like you are thinking of getting key presses "in real time", like might be useful in a game for example. But cin does not work like that. There is no way to "detect when user presses enter" in standard C++! So you can not end the program when user presses enter. What you can do is end the program when user enters empty line, or when user enters for example "quit" (or whatever, up to you), but every user input must end in them pressing enter.
Reading from cin is just like reading from a text file, except this text file gets a new line every time user presses enter. So closest thing to detecting user pressing enter is using std::getline:
std::string line
std::getline(std::cin, line);
This will get all characters from stdin until a newline (or until end of file), which usually means user pressed enter, when this is used in a console application. Note that the actual end-of-line will not be stored in the string, so if user just pressed enter without typing anything else, line will be empty string.
Looking at question after edit, you could replace cin >> rpsYou; with getline(cin, rpsYou);. You might then also want to add trimming the string you read, in case user for example typed extra spaces.
Related
I am currently working on a text based adventure game as a project for class. I have mostly everything started and working fine. The only problem is when I ask the user which room they want to change to, if they enter a blank input, then a message should output saying "You must choose a room." For the life of me I cannot figure it out. Any help is much appreciated.
Code:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main() {
bool game_play = true;
bool game_start = true;
int room_change;
int room_current = 0;
while (game_play == true) {
if (game_start == true) {
srand((unsigned int)time(NULL));
room_change = rand() % 2 + 1;
game_start = false;
}
else {
for (bool check = false; check == false;) { // Check if input is invalid
cin >> room_change;
if (cin.fail()) {
cout << "Choose an existing room.";
cin.clear();
cin.ignore();
}
else if (room_change == room_current) {
cout << "You're already in that room.";
}
else {
check = true;
}
}
}
switch (room_change) {
case 1:
cout << "You are in room 1.";
room_current = 1;
break;
case 2:
cout << "You are in room 2.";
room_current = 2;
break;
case 3:
game_play = false;
break;
default:
cout << "That room doesn't exist.";
}
}
return 0;
}
I just ran your code and when you hit enter, it will keep waiting until you enter a number or something invalid such as a character or a string. I did find that if you change your code from
cin >> room_change;
to
cin >> noskipws >> room_change;
when the user inputs a blank, it will cause the cin.fail() to return true and then proceed to print "Choose an existing room."
In your situation, the while loop will keep getting called until we have valid input. The "Choose an existing room" does get repeated because room_change is an integer, so when we hit enter, the '\n' will be left in the buffer. The while loop on the next iteration then reads that '\n' and executes the cin.fail() before letting you input something else. One solution I found is to use more cin.ignore() statements.
for (bool check = false; check == false;) { // Check if input is invalid
cin >> noskipws >> room_change;
if (cin.fail()) {
cout << "Choose an existing room.";
cin.clear();
cin.ignore();
} else if (room_change == room_current) {
cout << "You're already in that room.";
cin.ignore();
} else {
check = true;
cin.ignore();
}
}
The reason is because we want to get rid of that '\n' so that the cin.fail() does not execute. However, I did find that when you input a character, it will print "Choose an existing room" twice. It will print the first time because a character is not an integer, and a second time because of that '\n'.
The only problem is when I ask the user which room they want to change to, if they enter a blank input, then a message should output saying "You must choose a room."
Using std::getline and then extracting the number from the line using a std::istringstream is a better strategy for that.
std::string line;
std::cout << "Choose an existing room. ";
while ( std::getline(std::cin, line) )
{
// Try to get the room_change using istringstream.
std::istringstream str(line);
if ( str >> room_change )
{
// Successfully read the room.
break;
}
// Problem reading room_change.
// Try again.
std::cout << "Choose an existing room. ";
}
#include <iostream>
using namespace std;
int main(){
int room_change=200;
cout<<"Enter Blank";
cin>>room_change;
if(room_change==NULL){
cout<<"There is NO-THING"<<endl;
}
if(room_change!=NULL){
cout<<"There is something and that is :"<<room_change<<endl;
}
return 0;
}
But a much simpler approach to this would be to use Strings. If this is a Homework of sort and you are limited to Integer variable only. Its much more complicated if you want to detect if an Buffer is empty or not. Regardless of homework limitation, the OS layer input is String based. How can I use cin.get() to detect an empty user input?
So the problem is: Write a program that prints the question "Do you wish to continue?" and reads the input. If the user input is "Y", "Yes", "YES", then print out "Continuing". If the user input is "N" or "No", "NO" then print out "Quit". Otherwise, print "Bad Input". Use logical operators.
So far this is all the code that I have written. I know that it is not complete, and I do not know what else I need to add to the code.
#include <iostream>
using namespace std;
int main() {
char response;
cout << "Do you wish to continue?" ;
cin >> response;
if (response == 'Y'){
cout << "Continuing";
}
else if (response == 'N'){
cout << "Quit";
}
else if (response != 'N' || 'Y'){
cout << "Bad input";
}
return 0;
}
Update: so I edited my code and it is still giving me a bunch of errors. It's making me frustrated lol. Keep in mind I'm a beginner and we haven't learned loops yet. Sorry for the headache!
#include <iostream>
#include <string>
using namespace std;
int main() {
char response;
string help;
cout << "Do you wish to continue?" ;
cin >> response, help;
if (response == 'Y' || help == "Yes" || help == "YES"){
cout << "Continuing";
}
else if (response == 'N' || help == "No" || help == "NO"){
cout << "Quit";
}
else if (response != 'N' || response != 'Y' || help != "Yes" || help != "YES" || help != "No" || help != "NO"){
cout << "Bad input";
}
return 0;
}
First off I think this is a great start. Sounds like you are new to C++ so here are some suggestions:
1) Your response variable can only contain a character. I would suggest including string and changing the response to take a string from the user for 'Y', "Yes", etc.
2) I suggest wrapping your code in a while loop with an exit condition.
3) Each of your logic branches should include a return integer. This will give the program an exit condition if the logical conditions are met.
I know I haven't given you the answers fully. If you are truly stuck, reply back and we can walk through.
A simple way is to simply convert the user's answer to uppercase or lowercase. By doing this, you can simply use the lower case.
For your loop, you could for example use a "do..while".
#include <iostream>
#include <string>
using namespace std;
int main() {
int stop = 0;
string response;
//Continue until the user choose to stop.
do{
//-------------
// Execute your program
//-------------
cout << "Do you wish to continue? ";
cin >> response;
//-------------
//Convert to lower case
for (string::size_type i=0; i < response.length(); ++i){
response[i] = tolower(response[i]);
}
//-------------
//Check the answer of the user.
if (response.compare("y") == 0 || response.compare("yes") == 0){
cout << "Continuing \n";
}
else if (response.compare("n") == 0 || response.compare("no") == 0){
cout << "Quit \n";
stop = 1;
}
else{
cout << "Bad input \n";
}
}while(stop == 0);
return 0;
}
Like you said in the question, we care about Y,Yes,YES,N,No and NO. For anything else we need to print "Bad Input". Think about how you'd be storing these responses (hint: Sam Varshavchik's answer).
Once you've taken care of extracting user input, you'd want to check what the user actually entered and proceed accordingly. From your question it seems "if else" would do. You need to change the conditionals for your "if else ifs" because
you have 3 conditions for one type of response: Y, Yes and YES need one output - "continuing" while N, No and NO require a different output - "Quit" and for all others we print "Bad input". Think about what your conditionals should be and your if statement should look something like:
if (response == "Y" || response == "Yes" || response == "YES")
and then handle the case accordingly. You'd want to do the same for your No conditions and finally handle the case for all others. I'd suggest having your code like so:
if( conditionals for Yes){
//Code for Yes input
}
else if( conditionals for No){
//Code for No input
}
else{
//Code for all other inputs
}
It is tempting to give you the full answer but think about how your program needs to flow and proceed from there, you've almost got it!
If you have more questions post here and we'd be glad to help!
I've just started learning the basics in C++ and currently am trying to make a program that does a few basic things. The problem I have is occurring in the pasted function below.
At this point it literally does nothing when it runs. All I'm trying to do it make it so the function runs over and over again forever, until the user enters the letter 'q'.
The function must keep running even if the user enters some random string, anything, 'q' is the only keystroke that should stop the loop.
I have tried toying around with 'cin.whatever" and haven't found success. If you have an answer please provide as much explanation as possible. Thank you!
void menu()
{
cin.clear();
cin.ignore();
char quit = 'w';
while (quit != 'q') // while loop to allow the user infinite tries
{
cout << "Which story would you like to play? Enter the number of the story (1, 2, or 3) or type q to quit: " << endl;
cin >> quit;
if (quit < '1' or quit > '3') // make sure the user picks a valid choice
{
cout << "Valid choice not selected." << endl;
}
if (quit == '1')
{
story1(); // run story 1
}
if (quit == '2')
{
story2(); // run story 2
}
if (quit == '3')
{
story3(); // run story 3
}
if (quit == 'q')
{
cout << "good bye" << endl;
break;
}
}
}
Try adding single quotes around your 1,2,3 like you did with the q. The cin is expecting a char to be entered so evaluate it as such. e.g: if (quit == '1')
Following is the code for a login program that inputs the username, and then the password, while echoing '*' for every character entered, and then compares the username and password to preset values to see if they match and exits the program if it is true, else it goes back to the beginning.
int main()
{
int i = 0; string u; char parr[i + 1], ch;
while (1)
{
system("cls");
cout << "Enter username." << endl;
cin >> u;
system("cls");
cout << "Enter password." << endl;
i = 0;
while (1)
{
tag:ch = getch();
if (ch == '\r')
{
break;
}
if (ch == '\b')
{
cout << '\b';
--i;
ch = '\0';
parr[i] = '\0';
cout << ' ' << '\b';
goto tag;
}
parr[i] = ch;
ch = '*';
cout << ch;
++i;
}
parr[i] = '\0';
string p = "password";
if (u == "username" && parr == p)
{
system("cls");
cout << "Welcome!";
break;
}
else
{
system("cls");
cout << "Username and password entered does not match! Please try again.";
}
getch();
}
getch();
}
Now, here's the problem: Recently, I found out that this method of input (for the password) doesn't work as intended with Backspace, Delete, or the arrow keys. All of these keys input certain symbols instead of deleting characters or moving the cursor. So I tried out a workaround (currently only) for the backspace key. All worked fine- the previous character was deleted when I pressed backspace, but in the end, after the comparison with the preset values, it showed that the password doesn't match.
If you could please help me in the following:
*Working backspace functionality (and delete and arrow keys if possible)
*Pressing Esc at ANY point of the program quits it.
*I have used goto in this program, whose atrocities we all already know of. Please suggest me a way to avoid this, and also to make all this code neater than its current messy state.
Use continue instead of goto. In your case this will do the same: jump to the start of the loop.
Then run a debugger and watch what happens with your array if you input backspaces.
I'm making a small program that uses a if else statement, but instead of using numbers to control the flow i want to be able to make the control work with with yes and no;
for example:
cout << "would you like to continue?" << endl;
cout << "\nYES or NO" << endl;
int input =0;
cin >> input;
string Yes = "YES";
string No = "NO";
if (input == no)
{
cout << "testone" << endl;
}
if (input == yes)
{
cout << "test two" << endl;
//the rest of the program goes here i guess?
}
else
{
cout << "you entered the wrong thing, start again" << endl;
//maybe some type of loop structure to go back
}
but I can't seem to get any variations of this to work, i could make the user type a 0 or 1 instead but that seems really stupid, i'd rather it be as natural as possible, users don't speak numbers do they?
also i need to be able to simply add more words, for example "no NO No noo no n" all would have to mean no
hopefully that makes some sense
also i would love to make this using a window but i've only learned basic c++ so far not even that and i cant find any good resources online about basic windows programming.
You're not reading in a string, you're reading in an int.
Try this:
string input;
instead of
int input = 0;
Also, C++ is case-sensitive, so you can't define a variable called Yes and then try to use it as yes. They need to be in the same case.
btw, your second if statement should be an else if, otherwise if you type in "NO" then it will still go into that last else block.
First of all, input must be std::string, not int.
Also, you've written yes and no wrong:
v
if (input == No)
// ..
// v
else if (input == Yes)
^^^^
If you want your program to work with "no no no ..", you could use std::string::find:
if( std::string::npos != input.find( "no" ) )
// ..
The same with "Yes".
Also, you could do this to be almost case-insensitive - transform the input to upper-case letters (or lower, whatever ), and then use find.This way, yEs will be still a valid answer.
bool yesno(char const* prompt, bool default_yes=true) {
using namespace std;
if (prompt && cin.tie()) {
*cin.tie() << prompt << (default_yes ? " [Yn] " : " [yN] ");
}
string line;
if (!getline(cin, line)) {
throw std::runtime_error("yesno: unexpected input error");
}
else if (line.size() == 0) {
return default_yes;
}
else {
return line[0] == 'Y' || line[0] == 'y';
}
}
string input;
cin >> input;
if (input == "yes"){
}
else if (input == "no"{
}
else {
//blah
}