Using var for a switch case - c++

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.

Related

VSCode Debug opens stl_map.h when attempting to step into function to debug it

I am attempting to debug a graph function that starts at one vertex and ends at a destination vertex upon finding it via a FS (First Search) algo. Upon calling the function during debug mode, the debugger opens stl_map.h (I assume it does this because the graph (vertices and edges) have been implemented within a map.
The parameters of the function are (map, startPerson, endPerson). I pass a map, and the two people parameters as follows (name of the function is bfsFacebook):
for (;;) {
cout << endl << "Enter the name of the starting person:\n";
getline(cin, startingPerson);
if (IS_QUIT(startingPerson))
break;
if (everyone.count(startingPerson) == 0) {
cout << "Invalid starting name.";
continue;
}
cout << endl << "Enter the name of the ending person:\n";
getline(cin, endingPerson);
if (IS_QUIT(endingPerson))
break;
if (everyone.count(endingPerson) == 0) {
cout << "Invalid ending name.";
continue;
}
//Breath-First search from starting node to end node (starting vertext to end vertex)
if (bfsFacebook(everyone, everyone[startingPerson], everyone[endingPerson]) == true) {
cout << "Path found between " << startingPerson << " and " << endingPerson << endl;
} else {
cout << "Path Not Found between " << startingPerson << " and " << endingPerson << endl;
}
}
cout << "Exiting..." << endl;
Here is the actual function:
bool bfsFacebook(map<string, Person> everyone, Person &startingPerson, Person &endingPerson) {
startingPerson.visited = true;
if (startingPerson.name == endingPerson.name && startingPerson.visited == true)
return true;
for (string somePerson : startingPerson.friends) {
if (everyone[somePerson].visited == false && bfsFacebook(everyone, everyone[somePerson], endingPerson)) {
return true;
}
}
return false;
}
Is there any particular reason why stepping into the function during debugging does not send me to the actual function?
If my question is not detailed enough, please let me know.
The call line:
bfsFacebook(everyone, everyone[startingPerson], everyone[endingPerson])
Starts by resolving the arguments before calling bfsFacebook with them.
You have two calls to map<string, Person>::operator[](const string&) which shall be done to resolve everyone[startingPerson] and everyone[endingPerson], so the next executed line in your program is in std::map
The map<Key, Value>::operator[](const Key&) may be optimized depending on the build, but in debug it's more likely to be present in the code.
As the std::map has been instantiated for <string, Person> by your own code, the debugger has no reason not to step in a function which existence is your responsibility.

Codeblocks c++ code compiles correctly, but console is downsizing itself and not showing the entire output

Basically, whenever I run this program, the output window downsizes itself and I can only see the very end of it. Everything else is not shown even if I resize the console myself, which means that while I can work on it, I can't see most results.
This is how it looks when it first opens
How it looks when I resize it
The code uses a lot of headers, so I'm leaving only the main in order to give you an idea of what I'm working with. Most things are in spanish as I'm natively a spanish speaker (and am required to code in spanish).
It's just a simple menu that allows you to input a specific amount of customers attending a veterinary.
I have no idea what the issue is, and because I'm working with people who are more knowledgeable in coding than me, I can't exactly debug it myself either.
I'm running on CodeBlocks 17.12, on Windows 10.
int main(){
int opcion;
bool salir = false;
do{
system("cls");
cout << "\tBienvenido. Elija la opcion.\n\n";
cout << "\t1)Registrar socio.\n";
cout << "\t2)Agregar mascota.\n";
cout << "\t3)Ingresar consulta.\n";
cout << "\t4)Ver Socios ingresados.\n\n";
cout << "\t0)Salir\n\n";
cout << "\tOpcion: ";
fflush( stdin );
scanf("%d",&opcion);
if (opcion==1){
menuRegistrarSocio();
}
else if (opcion==2){
cout << "Ingrese los datos de la mascota\n";
system("PAUSE");
}
else if (opcion==3){
cout << "Ingrese los datos de la consulta\n";
system("PAUSE");
}
else if (opcion==4)
{
if(sistema.SOCIOS.size() == 0)
{
cout << "No hay socios creados" << endl;
}
else
{
int cont = 1;
map<char*, Socio*>::iterator i = sistema.SOCIOS.begin();
while(i != sistema.SOCIOS.end())
{
cout << cont << "- Nombre: " << i->second->getNombre() << " CI: " << i->second->getCi() << endl;
cont = cont + 1;
i++;
}
}
system("PAUSE");
}
else if (opcion==0){
salir = true;
}
else
cout << " - Comando Incorrecto\n";
}while (!salir);
cout << "\n\n - BYE!\n";
}
All I need is for the output to show correctly, so I can keep coding.
EDIT:
I "fixed" it by quoting the "system("cls");" line. There's a few other system lines in the code, so I quoted them as well, because they were causing the same effect.
I don't really know what they do (never used this before), but now the program isn't completely unusable. The window will still downsize itself, but it shows everything this time, so I can resize it and use it as normal.
I would try right clicking on the top bar of the console window where it says "D:####..." Then clicking Properties > Layout and changing the width and height.

show class' objects using other function than main(), but called in main();

Hello I work on a project for university which has to contain classes.
I can't paste them here because it would take a lot to read hundreds of rows, but I have a class USER which works perfectly, but I also have a MainMenu() function written right before main(),which is the only one I call in main(), made with switch, which is supposed to redirect the console to classes' submenus or to show objects for every class, it depends on class.
Ok, from this MainMenu when I choose to go to Users List option, I want the console to show me the list of users, that means, all user class objects I created in main(). I thought of creating a new function with reference to class, but I don't know how to use it in this situation when I don't call it in main, and however i need to reffer to all objects in that class not to mention a specific object..
How can I do this because I only call that MainMenu() in main(), not write it here to be able to use the objects directly?
Be kind to me, I'm a beginner and I never dealt with this type of requisites. I would be grateful if you could help me solve this.
Have a nice day.
#include<iostream>
using namespace std;
class user{};
class B{};
class C{};
void MainMenu()
{
cout << " Main Menu" << endl;
cout << endl;
int chosenoption;
cout << "1.Users List" << endl;
cout << "2.Class B Submenu" << endl;
cout << "3.Class C submenu" << endl;
cout << "Type here the number of the option you want to choose: ";
cin >> chosenoption;
system("pause");
switch (chosenoption)
{
case 1:
system("cls");
cout << "There should be shown the list of users, here the only users i created in main are u1 and u2, and i need to make them and their attributes appear in this screen" << endl;
break;
case 2:
system("cls");
ClassBSubmenu();
break;
case 3:
system("cls");
ClassCSubMenu();
break;
default:
cout << endl;
cout << "Choose one of the available options only!" << endl;
cout << "Type here: " << endl;
}
}
void main()
{
User u1(...);
User u2(..);
}
ClassBSubmenu and ClassCSubmenu are functions created before MainMenu, but I haven't edited them too much
You might want to have an array of Users which you pass to the MainMenu() function.
User u[] = { User(...), User(..) };
When you pass an array, you are actually passing a pointer to the first element in the array, so the Users could be modified in MainMenu() and the changes would exist in main().
void MainMenu( User users[] )
{
...
users[0]
MainMenu( u );

How do I modify variables in a function from the main script in C++

I've been at this for a few hours now. I am making a small game in C++ and I am trying to figure out how I can edit variables from inside of a function. I can place the variables in the main() and edit them them there no problem, but I can't figure out what I need to do to edit from a function. Below is the function.
void HeroSelect(string& hero)
{
int gold = 20, health = 5, attack = 5, stats[2] = { health, attack };
string weapon;
cout << "Please choose your hero.\n";
cin >> hero;
if (hero == "Warrior" || hero == "warrior")
{
weapon = "Broad Sword";
cout << "You are a Warrior wielding a " << weapon << endl;
cout << "Good choice.\n"
<< "You start out with " << gold << " gold." << endl
<< "You have " << stats[0]<< " health and " << stats[1] << " attack.\n";
}
Above is the function definition and I want to be able to edit the health when the player gets attacked or say gets a stronger weapon. Below is the main() of the script.
void main()
{
double enter, room1, room2, room3, room4, BossRoom;
int, gold = 20; //This is used as part of check inventory and will be subtracted when necessary
string hero, weapon;
//Set decimal two places
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);
Intro(enter);
cout << "The first step in this adventure is to choose your hero. You can choose a warrior, a wizard, or an archer.\n";
HeroSelect(hero);
So let's say he gets a new weapon and it gives +1 attack how do I reflect that in the function? Would I create a separate function for this?
As the player goes through the game, they can type in "stats" whenever, and when they do I want it to display their current health and attack and then essentially just loop back to the beginning of the room or fight they are in.
I know I can make the changes to the variables if I made all of my loops and all of my if-else statements in main(), but I wanted to try this and keep my main script clean. I did stats as an array, because I think it is good to print the array as a list. Any help would be great. Thanks!
You may need to do a refresher on C++ and OOP. Your concept is not bad, but you can possibly make it better. (Granted if you really want to do something in a particular fashion, and you are able to do it in such fashion, then by all means just do it :P).
As mentioned in your comments, a re-engineering of the game design may be in order. You will want to establish a Hero class, with multiple variables or sub-classes as the attributes (for example: strength, health points, weapons class, armor class, etc. (We could go into a lower-level description, but i don't think it's necessary yet). If you plan to have multiple weapons, a weapons class might be a good idea as well, for example you could define the weapon stats: attack damage, attack rate, weapon durability etc...
In these classes you can create "Helper Functions" which you can then use to change the stats of the associated objects. Helper function could be public functions which would allow you to increment/decrement hero health or perhaps a helper function that will increase attack damage?
It seems like you're doing a good job learning, so hopefully you can visualize the idea here. Either way, keep on grinding and feel free to ask for a more in depth answer whenever necessary! I'd love to see your game when your ready for some testing!
There are several ways to handle this.
The first being to create a class which is covered in the comments and the answer by ejsd1989.
The second option is to make these variables global variables by creating them in the main and just pass them through each function by reference. This keeps your main clean like you desired.
For example:
void HeroSelect(string& hero, int &gold, int &health)
The third option is very similar to the second, and it is to store these variables in an array and just modify the array with each function.
Essentially, it boils down to creating a class or passing the variables to the functions you wish to use.
Main is not a script and there are some conceptual problems with design in question. Word by word answer would be: pass function parameters by reference. But it would not be a good solution for the task.
Please consider this example:
uint menu;
Hero * hero;
Room entrance, next[5];
entrance.Enter();
std::cout << "1st step in this adventure is to choose your hero." <<std::endl;
std::cout << "You can choose " <<std::endl;
std::cout << "(1) a warrior " << std::endl;
std::cout << "(2) , a wizard" << std::endl;
std::cout << "(3) , or an archer." << std::endl;
std::cout << "Please choose your hero." << std::endl;
std::cin >> menu;
switch( menu )
{
case 3 : { hero = new Archer; break; }
case 2 : { hero = new Wizard; break; }
default : { hero = new Warrior; break; }
}
hero->Weapon();
hero->Gold();
hero->Health();
hero->Attack();
std::cout << "Which room to enter? 1..5" << std::endl;
std::cin >> menu;
next[menu - 1].Enter();
if( 5 == menu )
{
std::cout << "You are attacked by a troll!" << std::endl;
hero->SetHealth( hero->GetHealth() >> 1 );
}
hero->Health();
You can handle hero types, room instances this way. Find properties of them that could be generalized and make differences via members or inheritance. Design it more carefully and you could minimize e. g. tons of couts and duplicated code branches.
class Room
{
static uint cntr;
std::string name;
public:
Room() : name ( "Room#" ) { if( cntr < 5 ) { name[ name.size() - 1 ] = cntr + '0'; } else { name = "BossRoom"; } ++cntr; }
void Enter() { std::cout << "You have entered " << name << "!" << std::endl; }
};
uint Room::cntr;
struct Limint
{
uint max;
uint curr;
Limint( uint init ) : max ( init ), curr( init ) {}
};
class Hero
{
protected:
std::string type;
uint gold;
Limint hp;
Limint attack;
std::string weapon;
public:
Hero() : type( "Hero" ), gold( 20 ), hp( 50 ), attack(5), weapon( "Kitchen knife" ) {}
uint GetHealth() { return hp.curr; }
void SetHealth( uint health ) { health = std::min( health, hp.max ); hp.curr = health; }
void Weapon() { std::cout << "You are a " << type << " wielding a " << weapon << ". Good choice!" << std::endl; }
void Gold() { std::cout << "You start out with " << gold << " gold." << std::endl; }
void Health() { std::cout << "You have " << hp.curr << " / " << hp.max << " health." << std::endl; }
void Attack() { std::cout << "You have " << attack.curr << " / " << attack.max << " attack." << std::endl; }
};
class Warrior : public Hero
{
public:
Warrior() { type = "Warrior"; weapon = "Broad sword"; }
};
class Wizard : public Hero
{
public:
Wizard() { type = "Wizard"; weapon = "Magic stick"; }
};
class Archer : public Hero
{
public:
Archer() { type = "Archer"; weapon = "Crossbow"; }
};
Have fun!

C++ How do I do a loop that add in new value and can delete existing value

thanks for reading this question.
Basically I am trying to do a code that can achieve the following:
User will be shown a list of details like this
Terminal View:
Please select the department you want to add participant:
1. Admin
2. HR
3. Normal
4. Back to Main Menu
Selection: 3
normal's Department
UserID: 85 [ Name: Andrew, Department: normal ]
UserID: 86 [ Name: Jacky, Department: normal ]
UserID: 90 [ Name: Baoky, Department: normal ]
Current Selected Participant :
Usage:
Type exit to return to main menu
Type remove userid to remove participant
Type add userid to add participant
Selection:
Question is :
I want to be able to like let user add as many participant as he want until he decide to 'exit' to main menu, but how do i store it in a string participant.
How do I detect user input is 'remove userid'
or 'add userid' and then get the userid
e.g add 86
then he add 90
then he decided to remove 90
how do the string keep up with it
Below is my code:
do
{
cout << "Current Selected Participant : " << participant << endl;
cout << "" << endl;
do
{
if(counter>0)
{
//so it wont print twice
cout << "Usage: " << endl;
cout << "Type exit to return to main menu" << endl;
cout << "Type remove userid to remove participant" << endl;
cout << "Type add userid to add participant" << endl;
cout << "" << endl;
cout << "Selection: ";
}
getline(cin,buffer);
counter++;
}while(buffer=="");
if(buffer.find("remove"))
{
str2 = "remove ";
buffer.replace(buffer.find(str2),str2.length(),"");
if(participant.find(buffer))
{
//see if buffer is in participant list
buffer = buffer + ",";
participant.replace(participant.find(buffer),buffer.length(),"");
}
else
{
cout << "There no participant " << buffer << " in the list " << endl;
}
}//buffer find remove keyword
if(buffer=="exit")
{
done=true;
}
else
{
sendToServer = "check_account#"+buffer;
write (clientFd, sendToServer.c_str(), strlen (sendToServer.c_str()) + 1);
//see if server return found or not found
readFromServer = readServer (clientFd);
if(readFromServer=="found")
{
//add to participant list
participant += buffer;
participant += ",";
}
}//end if not exit
}while(done!=true);
Some users suggest i store in a string set, how do i store in a string set, and how do i make terminal able recognize keyword like 'remove' and 'add' in the selection
then get the user id which is seperate by a whitespace.
Next is how to remove if i store in a string set and how to push new value in.
Don't store it in a string. Store it in a collection that allows easy insertion and removal, like a std::set<int>. When the process has finished you can convert the set to whichever representation you feel you need.
Here's a very simple example (not checked to see if it compiles and runs; that's left as an exercise for the reader!)
void handle_command(const std::string& command, std::set<std::string>& userids)
{
if (command.substr(0, 4) == "add ")
{
std::string uid = command.substr(4);
if (userids.find(uid) == userids.end())
userids.insert(uid);
else
std::cout << "Uid already added" << std::endl;
return;
}
else
throw std::exception("Unsupported command, etc");
}