I'm doing a scrolling menu, this is the code of my scrolling menu:
vector<string> menuVector;
int _tmain(int argc, _TCHAR* argv[]){
menuVector.push_back("Login");
menuVector.push_back("Exit");
scrollingMenu_();
cin.get();
return 0;
}
void scrollingMenu_(){
ShowConsoleCursor(false);
int pointer = 0;
while (true){
system("cls");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
welcome();
for (int i = 0; i < menuVector.size(); ++i){
if (i == pointer){
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 8);
cout << "\t\t\t\t\t\t> " << center(menuVector[i], 5) << " <" << endl;
}
else{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
cout << "\t\t\t\t\t\t " << center(menuVector[i], 5) << " " << endl;
}
}
while (true){
if (GetAsyncKeyState(VK_UP) != 0){
pointer -= 1;
//if menu option selected is before the first option, it will back to the last menu option
if (pointer == -1){
pointer = menuVector.size() - 1;
}
break;
}
else if (GetAsyncKeyState(VK_DOWN) != 0){
pointer += 1;
//if menu option selected is after the last option, it will back to the first menu option
if (pointer == menuVector.size()){
pointer = 0;
}
break;
}
else if (GetAsyncKeyState(VK_RETURN) != 0){
switch (pointer){ //this is the switch case
case 0:
cout << "\n\n\nStarting new game...";
Sleep(1000);
break;
case 1:
exit(0);
break;
}
break;
}
}
Sleep(150);
}
}
As for the case switch inside my scrollingMenu_() function, the switch case will not be the same sometime I called the function, is there something like scrollingMenu_(switchcase), so by that time when I'm calling the function then I can define what my switchcase will do. Otherwise I have to copy paste the same scrollingMenu() function code for the parts that I need to do a menu with different menu options, which looks kinda redundant. I tried to research it online, but I didn't know how to search so I didn't get what I want.
Thank you.
If I understand you correctly, you want to be able to have different "menus" in your vector, and therefore be able to do different things in the switch depending on what menu is currently "active"?
Then I suggest a completely different design. Instead of a vector of strings for the menu, and a switch statement to select between the behaviors, use two vectors: One for the menu text (like you already have), and one for the menu "actions".
Then instead of using a switch to select between the actions for a menu alternative, simply use the pointer as an index into the second vector to call the action.
You can do this quite easily with std::function in combination with std::bind or lambda expressions.
For the menu you currently have it would be something like
std::vector<std::function<void()>> actionVector;
// ...
// Set up the menu vectors for the current menu
menuVector = {
"Login",
"Exit"
};
actionVector = {
[]() { cout << "\n\n\nStarting new game..."; Sleep(1000); },
[]() { std::exit(0); }
};
scrollingMenu_();
// ...
else if (GetAsyncKeyState(VK_RETURN) != 0){
actionVector[pointer](); // Call the action
}
Related
In C/C++ I have scenario where if should be executed on the basis of empty size.
If size of variable a is 0 then string 'add name' should be printed otherwise 'leave it' string should be printed. But I have switch cases for encoding as well for each case there will be different if condition.
switch(encoding)
case utf:
if(a->size-5 == 0)
{
cout<<"add name";
}
else
{
cout<<"leave it";
}
case ansi:
if(a->size-4 == 0)
{
cout<<"add name";
}
else
{
cout<<"leave it";
}
case ansi8:
if(a->size-8 == 0)
{
cout<<"add name";
}
else
{
cout<<"leave it";
}
I want to do it in minimal way. So what is the best way to do that.
I don't fully understand what solution you are expecting, but - same as suggested in a comment - when removing duplication from your code we are left with:
if(a->size-offset == 0)
{
cout<<"add name";
}
else
{
cout<<"leave it";
}
Where offset can be determined via:
int offset = 0;
switch(encoding) {
case utf: offset = 5; break;
case ansi: offset = 4; break;
case asni8: offset = 8; break;
}
Probably a cleaner solution would be to use a polymorphic type such that differences in the encoding are encapsulated in virtual methods, and you can write:
if(a->check_size())
{
cout<<"add name";
}
else
{
cout<<"leave it";
}
I think that ternary operator is the best approach.
switch(encoding) {
case utf:
(a->size - 5 == 0) ? std::cout << "add name" : std::cout << "leave it";
break;
case ansi:
(a->size - 4 == 0) ? std::cout << "add name" : std::cout << "leave it";
break;
case ansi8:
(a->size - 8 == 0) ? std::cout << "add name" : std::cout << "leave it";
break;
}
I'd write your code like this:
//...
//assuming utf, ansi, and ansi8 are enumerated constants
static const int encoding2size[]={ [utf]=5,[ansi]=4,[ansi8]=8 };
//...
if(a->size - encoding2size[encoding] == 0) cout<<"add name";
else cout<<"leave it";
//...
Maybe create a separate function for the if-else part that takes in an offset as input, and call the function with the desired input (desired offset) from each case in the switch case statement? This will at least help avoiding code duplication.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
Well basically I have this main method
int main() {
GameMapDriver* gameMapDriver = new GameMapDriver();
int players = 0;
std::cout << "How many players are going to play the game? Insert a numeric value from 2 to 5 : ";
std::cin >> players;
if ( players == 2 )
gameMapDriver->createGameMapForNumberOfPlayers(2);
switch (players) {
case 2 : {
gameMapDriver->createGameMapForNumberOfPlayers(2);
break;
}
case 3: {
gameMapDriver->createGameMapForNumberOfPlayers(3);
break;
}
case 4: {
gameMapDriver->createGameMapForNumberOfPlayers(4);
break;
}
case 5: {
gameMapDriver->createGameMapForNumberOfPlayers(5);
break;
}
default: std::cout << "Invalid number of players";
break;
}
return 0;
}
and for the gameMapDriver->createGameMapForNumberOfPlayers(2) method (please note that the first if statement is for debugging purposes, it shouldn't affect anything), I have this (I cropped the picture, the switch is coded correctly with default case at the end):
GameMap * GameMapDriver::createGameMapForNumberOfPlayers(int players){
std::cout << "Creating map";
switch (players){
case (TWO):{
this->gameMap = NULL;
delete this->gameMap;
this->gameMap = new GameMap(TWO);
std::cout << "Game map for two players created";
return this->gameMap;
break;
}
case (THREE) : {
this->gameMap = NULL;
delete this->gameMap;
this->gameMap = new GameMap(THREE);
std::cout << "Game map for three players created";
return this->gameMap;
break;
}
case (FOUR): {
this->gameMap = NULL;
delete this->gameMap;
this->gameMap = new GameMap(FOUR);
std::cout << "Game map for four players created";
return this->gameMap;
break;
}
case (FIVE):{
this->gameMap = NULL;
delete this->gameMap;
this->gameMap = new GameMap(FIVE);
std::cout << "Game map for five players created";
return this->gameMap;
break;
}
default: {
std::cout << "Invalid number of players";
return this->gameMap;
break;
}
}
}
The problem is that from createGameMapForNumberOfPlayers, line 21
std::cout << "Creating map";
it doesn't even print on console.
I run my app, I enter "2", I read it, I should be passing it to my method but it just says (exit value -1).It doesn't even print "Creating Map" at all.
What's happening? :(
You should use a debugger, but if you can't then at least you should flush cout to get a better idea of where your program is going wrong.
std::cout << "Creating map" << std::endl;
std::endl will add a newline to the output stream and more importantly force output to happen immediately. I would guess that your program is crashing while the output is still waiting to happen.
I have to do a C++ program to manage bank accounts. But i'm stuck. I need to display the different accounts, to select one and do some stuff on the selected account. I'm doing the choice in a switch case but i would like the "case" to be dynamic (an other part of the program is made for adding account)
switch (choixMenu)
{
case 1:
//Consulter un compte
do {
cout << endl << " ----------------------- CONSULTATION -----------------------" << endl << endl;
cout << "Choisir le compte a consulter : \n" << endl;
while (nCompte != NULL) {
int numCompte = 1;
int *ptr (0);
ptr = &numCompte;
cout << numCompte << " - " << nCompte << cid << endl;
numCompte++;
switch (choixConsul) {
case ptr :
}
}
cin >> choixMenu;
if (choixMenu != 1 && choixMenu != 2 && choixMenu != 3)
{
cout << "Choix invalide !" << endl;
}
} while (choixConsul != 3);
(compte = account)
Is there any way to do the case with a var? A loop to display the different account and a case in a loop to select every account?
Thanks for help! :)
A dynamic solution is to use tables:
struct Menu_Entry
{
std::string option_text;
void (*p_action_function)();
}
std::vector<Menu_Entry> menu;
With a table driven system, you could have one function that displays all the selections, then dereferences a function pointer associated with the menu choice.
Several menus can be displayed and processed by passing a vector of menu selections to the menu processing function.
The std::string could be replaced with an array of characters in order to allow for static constant data.
Using C++ What could possibly the best way for a sequence to run only once? To make it clearer for example that I have a program in where you need to guess a string, if the user entered hint I would display the hint of the word but I would only allow it once... I am currently doing this:
bool hintLock = false;
...
if (guess == "hint"){
if (!hintLock){
cout << hint << endl;
hintLock = true;
}
else
cout << "I've given you the hint" << endl;
}
Here's my code:
#include <iostream>
#include <string>
using namespace std;
void main(){
string guess;
bool hintLock = false;
cout << "Guess one of StackExchange's best site: Type \"hint\" for hint" << endl << endl;
do{
cout << "Guess > ";
cin >> guess;
if (guess == "hint"){ // Here it is
if (!hintLock){
cout << hint << endl;
hintLock = true;
}
else
cout << "I've given you the hint" << endl;
}
}
while (guess != "stackoverflow");
cout << "You've got it right!" << endl;
}
Is there any much better statement to do this? or is it already the best?
I suspect that either you are overanalyzing things or you haven't adequately described the real problem. From the code you've posted, I see no reason why you shouldn't wrap the code you want to execute in to a function and then simply call that function one time.
void blahBlah()
{
// blah blah
}
int main()
{
if (userInput == "hint")
blahBlah();
}
Perhaps what you meant is that in your program you have a main loop which executes until program termination, and in that loop you accept input from the user. The user is allowed to ask for a hint, but only once during the program's run. The first time the ask for a hint they are given one, but subsequent times they are not.
I still believe simple is better than fancy (read: complex). To that end, I start with having a bool scoped outside of the main loop which you check each time they ask for help:
int main()
{
bool displayedHint = false;
// program's main loop
for (bool endProgram = false; !endProgram; )
{
std::string command = getUserInput();
if (command == "hint")
{
if (displayedHint)
{
cout << "I already gave you a hint!\n";
}
else
{
displayHint();
displayedHint = true;
}
}
}
}
If you want to make sure it only shows once for any particular run of the program (anything more global than that is pretty complicated and platfrom-specific), all you need is a global boolean to protect the function. For example:
bool shownHint = false;
void showHint() {
if (!shownHint) {
cout << "The hint is: ........" << endl;
shownHint = true;
} else {
cout << "Hint has already been shown, no cheating!" << endl;
}
Whenever you think you might want to show the hint, call showHint() and it will show (or not) as appropriate.
The trick is making sure the variable is global (or a static, in a class, which looks almost the same), so that it doesn't get reset during your loop or otherwise while the program is running.
If you need to persist between runs, you could write to a file, check a server, set a registry key, or any number of other options.
I think that the most appropriate iteration statement is do-while. It allows at least one iteration
for example
do
{
std::cout << "Enter your word: ";
std::string answer;
std::cin >> answer;
// some other stuff
} while ( false );
Or
bool allow = true;
do
{
std::cout << "Enter your word: ";
std::string answer;
std::cin >> answer;
// some other stuff
} while ( allow = !allow );
You can use flags that are boolean, that represent a state in your system. Once the state is "defined", you can then query the state and find if it is "set" or "cleared"..
to be more precise
bool hasHinted = false; // unset or cleared( also definition of a state variable)
if(hasHinted == false){
//do something
hasHinted = true; // set
}else{
// do nothing
}
I think the OP is looking for a piece of code similar to singleton init. i.e.: only create the singleton once, and after that always return the pointer.
void Init() {
static bool isInitialized = false;
if (!isInitialized) {
isInitialized = true;
doRealInit();
}
}
the same thing done with std::call_once as a comment suggests:
std::once_flag flag;
void do_once() {
std::call_once(flag, [](){ std::cout << "Called once" << std::endl; });
}
in my opinion it's not really more readable or shorter.
I am practicing some code implementing different data structures. For this example I am trying to implement a simple stack data structure. So far it works as intended, but I keep getting Hex characters when trying to display my stack. Could anyone help me with figuring out why this is the case?
Also I am trying to get better at structuring my code properly, can anyone that is already involved in the industry please give me some constructive criticism as to what I have coded so far. Thanks.
#include <iostream>
using namespace std;
// stack_MAX == maximum height of stack
const int stack_MAX = 10;
class stack{
public:
stack(){
//Constructor initializes top of stack
top = -1;
}
bool isFull(int top){
//isFull() will check to make sure stack is not full
//Will return TRUE if stack is FULL, and FALSE if
//stack is NOT FULL
if(top == stack_MAX - 1)
return true;
else
return false;
}
bool isEmpty(int top){
//isEmpty() will check to make sure stack is not empty
//Will return TRUE if stack is EMPTY, and FALSE if
//stack is NOT EMPTY
if(top == -1)
return true;
else
return false;
}
void push(int x){
//push() will push new element on top of stack
if(isFull(top)){
cout << "Sorry, but the stack is full!" << endl;
exit(1);
}
else{
top++;
x = stk[top];
}
}
void pop(){
//pop() will pop the top element from the stack
if(isEmpty(top)){
cout << "Sorry, but the stack is empty!" << endl;
exit(1);
}
else{
cout << stk[top] << " is being popped from stack!" << endl;
top--;
}
}
void display_stack(){
//diplay_stack() will show all elements currently in the stack
int temp; //will temporarily hold position of stack
temp = top;
while(!isEmpty(temp)){
cout << stk[temp] << endl;
temp--;
}
}
private:
int top;
int stk[stack_MAX];
};
int menu(){
int choice;
cout << "Welcome to my stack!" << endl;
cout << "What would you like to do? (select corresponding #)" << endl << endl;
cout << "1. Push" << endl;
cout << "2. Pop" << endl;
cout << "3. Display" << endl;
cout << "4. Quit" << endl;
cin >> choice;
return choice;
}
int main()
{
int selection, x;
stack myStack;
selection = menu();
while(selection != 4)
{
switch(selection){
case 1:
cout << "please enter number to be pushed: ";
cin >> x;
myStack.push(x);
selection = menu();
break;
case 2:
myStack.pop();
selection = menu();
break;
case 3:
myStack.display_stack();
selection = menu();
break;
default:
cout << "Oops that's not a selection, try again" << endl;
selection = menu();
break;
}
}
cout << "Thank you for stopping by and using my stack!" << endl;
system("pause");
return 0;
}
A statement in your push functin is wrong, modified as below:
void push(int x)
{
//push() will push new element on top of stack
if(isFull(top))
{
cout << "Sorry, but the stack is full!" << endl;
exit(1);
}
else
{
top++;
/***************************
x = stk[top];
****************************/
stk[top] = x;
}
}
Advice:
Learn to debug, here is the tutorial
Include the head file cstdlib when you want to use exit in your
code
Do not name your class with the same name for any classes in STL
As pointed out by prehistoric penguin, your push() function is incorrect:
x = stk[top];
Should be changed to:
stk[top] = x;
I wanted to comment anyway to offer some general comments as you requested:
If statements like this can be replaced by a single line of code:
if(top == stack_MAX - 1)
return true;
else
return false;
becomes:
return (stack_MAX - 1 == top);
Put constant expressions on the left-hand side of your comparison expression. For example:
(top == stack_MAX - 1)
becomes:
(stack_MAX - 1 == top)
The reason is that one day you will accidentally type something like:
(top = stack_MAX - 1)
and you or somebody else will waste a lot of time debugging it :)
Your isFull() and isEmpty() functions shouldn't take a parameter. They should just use the private member variable top. How would somebody call these functions without access to top, which you've correctly made a private member?
In general, avoid using. In my opinion it defeats the whole purpose of namespaces. using namespace std is a commonly used exception, but even then, is it so hard to type std::cout?
Always put curly braces around the clauses of your if statement, even if they are just one line. It's easy to forget to add braces if you need to add more statements to a clause later on, which can be quite confusing.
Your code formatting is pretty good, but pick a bracket style and be consistent. Either always put the opening curly brace on the same line as the function header / control statements etc, or always put it on the line afterwards.
Hope that helps.