_getch not reading input into variable - c++

I'm having trouble with the _getch() function, I want it so that the user does not need to hit ENTER when selecting things from the menu. However, when I try and use it, it either doesn't input the data into a variable, or it skips over the switch I have. I'm using Windows 7, and the CodeBlocks IDE. What am I doing incorrectly? Thanks in advance.
#include <iostream>
#include <sstream>
#include <conio.h>
using namespace std;
stringstream ss;
int a;
void play()
{
cout << "\nYou wake up on the forest floor. You do not remember where you are, who you are, or anything\nthat has happened before you waking up. You seem to be some type of...\n";
cout << "--CHARACTER SELECTION--\n1. Warrior\n2. Mage\n3. Rouge";
cin.get();
};
int main()
{
// CreateDirectory()
cout << "--SELECTION MENU--\n1. Begin\n2. Delete Game\n3. Instructions" << endl;
a=_getch();
switch(a){
case 1:
play();
break;
case 2:
// delete();
break;
case 3:
// help();
break;
return 0;
}
}

Compare your char against the characters '1', '2' and '3' rather than the integers 1, 2 and 3.
switch(a){
case '1':
play();
break;
case '2':
// delete();
break;
case '3':
// help();
break;
return 0;
}

Related

Why am I getting an infinite loop when using do-while loop with my print function [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I'm trying to make a menu of different functions which supposed to run until the user inputs the 'Q' or 'q' character. When I try to run the program, it keeps on looping the default switch case. Am I using the wrong loop?
#include <iostream>
#include <vector>
using namespace std;
bool getout{false};
char cases ;
void menu(){
cout << "\n\nP - Print Number\nA - Add Number\nM - Display mean of the number\nS - Display the smallest number\nL - -Display the largest number\nQ - Quit\n\nEnter your choice: " << endl;
}
char read(){
cin>> cases;
}
int main(){
do{
void menu();
void read();
switch (cases){
case 'p':
case 'P': void print();
break;
case 'S':
case 's':
void smallest();
break;
case'Q':
case 'q':
getout=true;
break;
default:
cout<<"Please input a valid option";
}//switch braces
}
while (getout==false);
return 0;}
Your read() function doesn't return anything in spite of being marked as returning a char. You call the function incorrectly in your main function as well. This is the main culprit.
Remove the word void.
I've attached a touched-up version of your code. It moves the global variables into the main function (globals are a thing to avoid whenever possible), and fixes the read function to return a character. I can never tell if the poor formatting in the question is a copy-paste issue, or your code is legitimately that sloppy, but in either case I also formatted it.
#include <iostream>
#include <vector>
void menu() {
std::cout
<< "\n\nP - Print Number\nA - Add Number\nM - Display mean of the "
"number\nS - Display the smallest number\nL - -Display the largest "
"number\nQ - Quit\n\nEnter your choice: ";
}
char read() {
char choice;
std::cin >> choice;
return choice;
}
int main() {
bool getout{false};
do {
menu();
char cases = read();
switch (cases) {
case 'p':
case 'P':
void print();
break;
case 'S':
case 's':
void smallest();
break;
case 'Q':
case 'q':
getout = true;
break;
default:
std::cout << "Please input a valid option";
} // switch braces
} while (getout == false);
return 0;
}

c++ obect out of scope inside a switch statement

The object derm is out of scope in the switch statement.
I tried to make it a static member function.
Is there anyway I can make this work?
Here is my code:
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <ctime>
using namespace std;
class Invinq {
int menu_pick;
string db_read_out;
public:
Invinq();
void menu_maker();
int add_record();
int change_record();
int delete_record();
int display_record();
int exit_program();
};
Invinq::Invinq()
{
cout <<"Welcome to Inventory Inquisator.\n********************************\n" << endl;
ifstream db_invinq;
db_invinq.open("Invinq_db.txt");
if(!db_invinq)
{
cout<<"\nNot able to create a file. MAJOR OS ERROR!! \n";
}
for(int i = 0; i < db_invinq.eof(); i++)
{
db_invinq >> db_read_out;
cout << db_read_out;
}
}
//Menu maker
void Invinq::menu_maker()
{
cout << "1. Add Record\n2. Change Record\n3. Delete Record\n4. Display Record\n5. Exit\n\nPick One: ";
cin >> menu_pick;
switch(menu_pick)
{
case 1: derm.add_record(); break;
case 2: derm.change_record(); break;
case 3: derm.delete_record(); break;
case 4: derm.display_record(); break;
default: cout << "Pick a number between 1-5, try again\n";
}
derm.menu_maker();
}
int main() {
Invinq derm;
derm.menu_maker();
return 0;
}
You seem to have completely missed the point. you don't need derm when you are already inside the Invinq class - just call menu_maker().
Having said that: you are using recursion for no good reason. This can have some unexpected side effects. I suggest you refactor menu_maker() - if fact right now there is no way to get out of the recursion, so that is really bad!
You main should have the loop and create a Invinq each time through, otherwise you are just overwriting the same object each time which is probably now what you want.
Inside the definition of your class method, you should refer to yourself using the keyword this.
Replace all the method calls as following:
case 1: derm.add_record(); break; > case 1: this->add_record(); break;
Note: this returns a pointer to your object, this is why we use -> rather than .

c++ While Loop termination with function

scratching my head on this as it was working just fine earlier but when I went to add some other functions suddenly my program freaked out and I can not get it back to what it was.
class has me writing a rock/paper/scissors program to go up against a computer, any help with why the loop keeps terminating itself would be wonderful
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
void RPSout(char);
int RPScomp();
int main() {
char choice;
int endit=0;
while (endit == 0)
{
cout << "\n\n\tReady to play Rock/Paper/Scissors against the computer??(please choose R/P/S)(Q to quit)\n";
cin >> choice;
RPSout(choice);
if (choice=='Q'||'q')
{endit=1;}
}
return 0;
}
void RPSout(char choose)
{
int RPS =0;
int comp=0;
switch (choose)
{
case 'R':
case 'r':
{
cout <<"Your choice: Rock";
break;
}
case 'P':
case 'p':
{
cout <<"Your choice: Paper";
break;
}
case 'S':
case 's':
{
cout << "Your choice: Scissors";
break;
}
case 'Q':
case 'q':
{
cout << "Bye Bye Bye";
break;
}
default:
cout<<"You enter nothing!"<<endl;
cout << "The valid choices are R/P/S/Q)";
}
return;
}
int RPScomp()
{
int comp=0;
const int MIN_VALUE =1;
const int MAX_VALUE =3;
unsigned seed = time(0);
srand(seed);
comp =(rand() % (MAX_VALUE - MIN_VALUE +1)) + MIN_VALUE;
return comp;
}
if (choice=='Q'||'q')
This is equivalent to
if ((choice == 'Q') || 'q')
Which is almost certainly not what you want. 'q' is a non-zero char literal, which is "truthy" and so this expression will never be false. It's akin to writing if (choice == 'Q' || true).
The solution is:
if (choice=='Q' || choice=='q')
The statement
if (choice=='Q'||'q')
always tests true and therefore sets your flag to terminate the loop.
Try:
if (choice=='Q'||choice=='q')
I think your if statement should be if (choice=='Q'|| choice=='q')
Your issue if with the if statement
if (choice=='Q'||'q')
{endit=1;}
the || 'q' part will always be true since 'q' in ASCII is not 0
Change your code to
if (choice=='Q'|| choice=='q')
{endit=1;}

Vectors, Pointers, Classes and EoF Loops (C++)

I am trying to get a vector to store objects of class 'Complex'.
This is how I have tried to get it to store:
ifstream values;
values.open("h://values.txt");
if(!values)
{
cout<<"Error: cannot open "<<"values.txt"<<endl<<endl;
}
else
{
//Initialise list
vector<Complex> v;
Complex *c1;
double a,b,d=0,e=0;
char c;
int count=0;
while(values)
{
values>>c>>a>>b;
c1=new Complex;
v.push_back(*c1);
cout<<c<<" "<<a<<" "<<b<<endl;
switch (c)
{
case 'r':
case 'R':
case 'p':
case 'P':
{
//Call constructor
v[count].setType(c);
switch (c)
{
case 'r':
case 'R':
{ v[count].setReal(a);
v[count].setImaginary(b);
v[count].topolar(a,b,d,e);
break;
}
case 'p':
case'P':
{ v[count].setLength(a);
v[count].setAngle(b);
v[count].frompolar(d,e,a,b);
break;
}
default:
{ cout<<"Type Error"<<endl;
break;
}
}
count++;
break;
}
default:
{
//error message
cout<<" Failed input type, ensure all of type 'r' or 'p'"<< endl;
cout<<"Programme Closing"<<endl;
break;
}
};
}
While this will read the info in my programme, it insists on reading the last line twice (I put the cout into this loop so it was easier to see what numbers were where). I have tried using a for loop, but because I want it to run till the end of file I think I have to use a while loop, but I might be wrong.
My supervisor said something along the lines of c1 being overwritten on every loop, but I thought this should be OK on the basis the information is passed to the vector before it is overwritten by the next line so I'm a bit confused.
The next problem is that when I then try and print out all the information again, outside of the loop shown above (for example to allow for manipulation before printing) it prints the same thing over and over until the for loop reaches the count...
int y;
int z;
while(y!=3)
{
cout<< " What would you like to do?"<<endl;
cout<< " Type the number of the option you would like"<<endl;
cout<< " 1. Show all numbers in polar form"<<endl;
cout<< " 2. Show all numbers in rectangular form"<<endl;
cout<< " 3. Show all numbers in both forms"<<endl;
cout<< " 4. Convert a number to its conjugate"<<endl;
cout<< " 5. Exit"<<endl;
cin>>y;
switch(y)
{
case 1:
for(z=0; z<count;z++)
{
v[z].getLength();
v[z].getAngle();
cout<< a<<" "<<b<<endl;};
break;
case 2:
for (z=0; z!=count;z++)
{
v[z].getReal();
v[z].getImaginary();
};
break;
case 3:
cout<<" Real Imaginary | Length Angle | Original Type"<<endl;
for(z=0; z!=count;z++)
{ v[z].getLength();
v[z].getAngle();
v[z].getReal();
v[z].getImaginary();
cout<<a<<" "<<b<<" "<<d<<" "<<e<<endl;
In case any of you try to run the programme:
#include "Class definitions.h"
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string.h>
#include <cmath>
#include <vector>
using namespace std;
Any help will be greatly appreciated!!
Thanks muchly!
H
x
Whether input succeeds is only known after the input, not before. After you do
values>>c>>a>>b;
you use the values, even if the input has failed (e.g. because of end of file). Put the test in the condition of the while loop:
while ( values >> c >> a >> b )
and your code should work. (Whether this is the best way to handle the problem is another question. I'd probably use std::getline(), followed by std::istringstream to parse the line I'd read. Much easier error recovery.)

How do I use an enum value in a switch statement in C++?

I would like to use an enum value for a switch statement. Is it possible to use the enum values enclosed in "{}" as choices for the switch()"?
I know that switch() needs an integer value in order to direct the flow of programming to the appropriate case number. If this is the case, do I just make a variable for each constant in the enum statement?
I also want the user to be able to pick the choice and pass that choice to the switch() statement.
For example:
cout << "1 - Easy, ";
cout << "2 - Medium, ";
cout << "3 - Hard: ";
enum myChoice { EASY = 1, MEDIUM = 2, HARD = 3 };
cin >> ????
switch(????)
{
case 1/EASY: // (can I just type case EASY?)
cout << "You picked easy!";
break;
case 2/MEDIUM:
cout << "You picked medium!";
break;
case 3/HARD: // ..... (the same thing as case 2 except on hard.)
default:
return 0;
}
You can use an enumerated value just like an integer:
myChoice c;
...
switch( c ) {
case EASY:
DoStuff();
break;
case MEDIUM:
...
}
You're on the right track. You may read the user input into an integer and switch on that:
enum Choice
{
EASY = 1,
MEDIUM = 2,
HARD = 3
};
int i = -1;
// ...<present the user with a menu>...
cin >> i;
switch(i)
{
case EASY:
cout << "Easy\n";
break;
case MEDIUM:
cout << "Medium\n";
break;
case HARD:
cout << "Hard\n";
break;
default:
cout << "Invalid Selection\n";
break;
}
Some things to note:
You should always declare your enum inside a namespace as enums are not proper namespaces and you will be tempted to use them like one.
Always have a break at the end of each switch clause execution will continue downwards to the end otherwise.
Always include the default: case in your switch.
Use variables of enum type to hold enum values for clarity.
see here for a discussion of the correct use of enums in C++.
This is what you want to do.
namespace choices
{
enum myChoice
{
EASY = 1 ,
MEDIUM = 2,
HARD = 3
};
}
int main(int c, char** argv)
{
choices::myChoice enumVar;
cin >> enumVar;
switch (enumVar)
{
case choices::EASY:
{
// do stuff
break;
}
case choices::MEDIUM:
{
// do stuff
break;
}
default:
{
// is likely to be an error
}
};
}
You can use a std::map to map the input to your enum:
#include <iostream>
#include <string>
#include <map>
using namespace std;
enum level {easy, medium, hard};
map<string, level> levels;
void register_levels()
{
levels["easy"] = easy;
levels["medium"] = medium;
levels["hard"] = hard;
}
int main()
{
register_levels();
string input;
cin >> input;
switch( levels[input] )
{
case easy:
cout << "easy!"; break;
case medium:
cout << "medium!"; break;
case hard:
cout << "hard!"; break;
}
}
I had a similar issue using enum with switch cases.
Later, I resolved it on my own....below is the corrected code, and perhaps this might help.
//Menu Chooser Programme using enum
#include <iostream>
using namespace std;
int main()
{
enum level{Novice=1, Easy, Medium, Hard};
level diffLevel = Novice;
int i;
cout << "\nEnter a level: ";
cin >> i;
switch(i)
{
case Novice:
cout << "\nyou picked Novice\n"; break;
case Easy:
cout << "\nyou picked Easy\n"; break;
case Medium:
cout << "\nyou picked Medium\n"; break;
case Hard:
cout << "\nyou picked Hard\n"; break;
default:
cout << "\nwrong input!!!\n"; break;
}
return 0;
}
You should keep in mind that if you are accessing a class-wide enum from another function, even if it is a friend, you need to provide values with a class name:
class PlayingCard
{
private:
enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES };
int rank;
Suit suit;
friend std::ostream& operator<< (std::ostream& os, const PlayingCard &pc);
};
std::ostream& operator<< (std::ostream& os, const PlayingCard &pc)
{
// Output the rank ...
switch(pc.suit)
{
case PlayingCard::HEARTS:
os << 'h';
break;
case PlayingCard::DIAMONDS:
os << 'd';
break;
case PlayingCard::CLUBS:
os << 'c';
break;
case PlayingCard::SPADES:
os << 's';
break;
}
return os;
}
Note how it is PlayingCard::HEARTS and not just HEARTS.
The user's input will always be given to you in the form of a string of characters... if you want to convert the user's input from a string to an integer, you'll need to supply the code to do that. If the user types in a number (e.g. "1"), you can pass the string to atoi() to get the integer corresponding to the string. If the user types in an english string (e.g. "EASY") then you'll need to check for that string (e.g. with strcmp()) and assign the appropriate integer value to your variable based on which check matches. Once you have an integer value that was derived from the user's input string, you can pass it into the switch() statement as usual.
#include <iostream>
using namespace std;
int main() {
enum level {EASY = 1, NORMAL, HARD};
// Present menu
int choice;
cout << "Choose your level:\n\n";
cout << "1 - Easy.\n";
cout << "2 - Normal.\n";
cout << "3 - Hard.\n\n";
cout << "Choice --> ";
cin >> choice;
cout << endl;
switch (choice) {
case EASY:
cout << "You chose Easy.\n";
break;
case NORMAL:
cout << "You chose Normal.\n";
break;
case HARD:
cout << "You chose Hard.\n";
break;
default:
cout << "Invalid choice.\n";
}
return 0;
}
You can cast enum with int.
enum TYPE { one, two, tree };
TYPE u;
u = two;
switch( int( u ) ){
case one :
action = do_something ;
break;
case two:
action = do_something_else;
break;
}