C++ switch not working with more than 2 cases [closed] - c++

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 8 years ago.
Improve this question
I'm learning C++ so sorry for newbie question.
I'm doing exercises from S. Prata's Book. I'm currently on 6.4.
There is the code I've written:
#include <iostream>
using namespace std;
void showmenu();
void request();
const int strsize = 20;
const int templeSize = 5;
struct temple {
char name[strsize];
char job[strsize];
char psd[strsize];
int preference;
};
int main(){
temple members[templeSize] = {
{"Alan", "spy", "Kret", 0},
{"Bruce", "engi", "Mech", 2},
{"Zac", "engi", "Robot", 0},
{"Kevin", "teacher", "Kid", 1},
{"Maverick", "spy", "Shadow", 2}
};
char choice;
showmenu();
request();
cin >> choice;
while (choice != 'q'){
switch(choice){
case 'a' : for(int i; i< templeSize; i++)
cout << members[i].name << endl;
break;
case 'b' : for(int i; i< templeSize; i++)
cout << members[i].job << endl;
break;
case 'c' : for(int i; i< templeSize; i++)
cout << members[i].psd << endl;
break;
case 'd' : for(int i; i < templeSize;i++){
switch(members[i].preference){
case 0: cout << members[i].name; break;
case 1: cout << members[i].job; break;
case 2: cout << members[i].psd; break;
}
}
default : request();
}
showmenu();
cin >> choice;
}
cout << "\nBye!\n";
return 0;
}
void request(){
cout << "Choose one option:\n";
}
void showmenu(){
cout << "a. names b. jobs\n"
"c. psds d. preferences\n"
"q. Quit\n";
}
I have no ide what is wrong with that. Code is compiling (I'm using code::blocks), but only for cases 'a' and 'b'. When I input 'c' or 'd' it just showing menu again. Same if I choose a/b more than once.
I've found other solution via google, but I realy want to know what is wrong with my code.

i is not initialized in any of your case statement for loops

You are calling showmenu() outside of your switch statement. So no matter what the input you will leave the switch and call the function.
switch(choice){
...
}
showmenu();
...

Related

C++ input error with switch statment and 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 8 months ago.
Improve this question
I don't know why but my code is not working when I sign out a book and click a number and then try to sign in a book it says I have the number one choice(Python book) even if i click any other option. I don't know why.It's probably something dumb so please go easy on me.
#include <iostream>
using namespace std;
string book;
void menu(){
cout << "*********Menu*********";
cout << "\n1) Sign out book";
cout << "\n2) sign in book";
cout << "\n3) See my books";
cout << "\n4) Exit";
}
void book1(){
book = {"Computer Science"};
}
void book2(){
book = {"Programming with C++"};
}
void book3(){
book = {"Python Programming"};
}
int main(){
//Vars
int choice;
do
{
menu();
cin >> choice;
switch (choice)
{
case 1:
int book_choice;
cout << "\n**********************";
cout << "\n1) Computer Science";
cout << "\n2) Programming with C++";
cout << "\n3) Python Programming";
cin >> book_choice;
switch (book_choice)
{
case 1:
book1();
case 2:
book2();
case 3:
book3();
default:
break;
}
break;
case 2:
cout << "\n**********************";
cout << "\nSigned out books: ";
cout << book;
//add books
case 3:
cout << "\n**********************";
default:
break;
}
} while (choice != 4);
}
The error lies in the book_choice switch:
switch (book_choice)
{
case 1:
book1();
// missing break;
case 2:
book2();
// missing break;
case 3:
book3();
// missing break;
default:
break;
}
You forgot to use break; after each case. The default behaviour in a switch is to fall through and execute the next case. That means you always end up executing book3() and setting your book to "Python Programming".

c++: for not working as intended [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 5 years ago.
Improve this question
My question is when I run the code,and call for the list,so I press 3,nothing happens and it just skips over the code in for(). Why does this occur and how can I fix it?
Simple code would be welcome.I am now to this.
The first two int before the main checks if the student is qualified for the school,or not.i tested those and they are working great.
The struct describes a student.He/She has a name(nev),marks (bacmagy,bacrom,bacmat,bacvalasz).A boolean value(langexam) is present,to represent is the student has a language exam or not.
bsiker is true,if the formula in calculateBac turns out to be true.
atmente is true,if bsiker and langexam are both true.
The listing would spit out the name,bsiker and atmente.
#include <iostream>
using namespace std;
int atmegye(bool elso, bool masodik){
if (elso && masodik)
return true;
else
return false;
}
int calculateBac(double magy, double mat, double rom, double val){
double osszeg = magy + mat + rom + val;
osszeg = osszeg / 4;
if (magy < 5 || mat < 5 || rom < 5 || val < 5 || osszeg < 6)
return false;
else
return true;
}
int main(){
struct diak{
char nev[32];
bool langexam, atmente, bsiker;
double bacmagy, bacrom, bacmat, bacvalasz, bac;
};
diak v[150];
bool cap = false;
int opcio;
int j, n = 0;
int i = 0;
do{
cout << "\n Welcome. \n 1-new studient \n 2-Change a studient's details \n 3-List \n 4-Exit \n";
cin >> opcio;
switch (opcio){
case 4:{
return 0;
}
case 1:{
cout << "Please give the name of the student: ";
cin >> v[i].nev;
cout << "Hungarian mark: ";
cin >> v[i].bacmagy;
cout << "Romanian mark: ";
cin >> v[i].bacrom;
cout << "Maths mark: ";
cin >> v[i].bacmat;
cout << "Optional mark: ";
cin >> v[i].bacvalasz;
cout << " Do you have a language exam? Please respond with 1 or 0: ";
cin >> v[i].langexam;
v[i].bsiker = calculateBac(v[i].bacmagy, v[i].bacrom, v[i].bacmat, v[i].bacvalasz);
v[i].atmente = atmegye(v[i].bsiker, v[i].langexam);
i = i + 1;
i = n;
cout << n;
break;
}
case 3: {
for(i = 0; i < n; i++)
cout << v[i].nev << " " << v[i].bsiker << " " << endl;
break;
}
}
}while (opcio != 5);
}
This line is wrong:
i = n;
it should be:
n = i;
Your code is just undoing the i = i + 1; line that precedes it.
n is initialized as 0 and never set to any other value. Therefore your for loop is not supposed to run any iteration
The problem is in the for loop's conditional. You initialized the value of n to 0, and that value never seems to change. The variable i is also initialized to 0 inside the for loop. When the user chooses option 3, the for loop conditional ( 0 < 0) is evaluated which is false, so the for loop is skipped every time. So, to fix this problem, you need to update the value of n somewhere in your code, or you need to change your conditional statement. Hope this helps!
I know this probably won't help for your assignment, but here's a (one of many) way to handle this is a more c++-like manner, and without using OOP.
The standard library and the c++ type system give us plenty of useful tools to avoid writing bugs in the first place (that's really nice!), and find the one that are left at compile-time (saves a ton of time!). That's what the biggest difference between c and c++ is, and it is a very important one.
#include <iostream>
#include <vector>
#include <string>
#include <string.h>
// fixed-size record to save in data file, for example.
struct diak{
char nev[32];
bool langexam, atmente, bsiker;
double bacmagy, bacrom, bacmat, bacvalasz, bac;
};
void atmegye(diak& student)
{
student.atmente = student.bsiker && student.langexam;
}
void calculateBac(diak& student) // computes grades average, checks if passed.
{
double osszeg = student.bacmagy + student.bacmat + student.bacrom + student.bacvalasz;
student.bac = osszeg / 4.0;
student.bsiker = student.bacmagy >= 5
&& student.bacrom >= 5
&& student.bacmat >= 5
&& student.bacvalasz >= 5
&& student.bac >= 5; // this last test unnecessary, but rules are rules.
}
void AddNewStudent(std::ostream& os, std::istream& is, std::vector<diak>& students)
{
diak new_student;
std::string temp;
while(temp.empty())
{
os << "Student name: ";
is >> temp; // using a temp buffer avoids out of bounds errors
}
if (temp.length() >= sizeof(new_student.nev))
temp.resize(sizeof(new_student.nev) - 1);
strcpy(new_student.nev, temp.c_str());
// input values below SHOULD be validated for range (0-100)
// or whatever makes sense for your school.
os << "Hungarian mark: "; is >> new_student.bacmagy;
os << "Romanian mark: "; is >> new_student.bacrom;
os << "Maths mark: "; is >> new_student.bacmat;
os << "Optional mark: "; is >> new_student.bacvalasz;
// example validation. Validating user input is the worst!
// above ^^^ grades ^^^ can use a common function for validation.
for(;;)
{
os << " Do you have a language exam? Please respond with 1 or 0:";
is >> temp;
if (temp == "0")
{
new_student.langexam = false;
break;
}
if (temp == "1")
{
new_student.langexam = true;
break;
}
// not a valid entry, try again!
}
calculateBac(new_student);
atmegye(new_student);
students.push_back(new_student);
}
void EditSudent(std::ostream& os, std::istream& is, std::vector<diak>& students)
{
// query which student then edit using streams 'os' and 'is' for i/o.
}
// could also be used to write to file...
void PrintStudents(std::ostream& os, const std::vector<diak>& students)
{
// maybe by printing a student number you could reuse this
// function from EditStudent()...
//
// At the same time, it is only 2 lines of code. You decide.
for(size_t i = 0; i < students.size(); i++)
os << students[i].nev << " " << students[i].bsiker << "\n";
os.flush();
}
int main()
{
std::vector<diak> students; // could also be an std::list<>
while(true) // 1 less line of code than do {...} while, and easier to read.
{
int opcio = 0;
std::cout << "\n Welcome."
"\n 1-new studient"
"\n 2-Change a studient's details"
"\n 3-List "
"\n 4-Exit \n";
std::cin >> opcio;
switch (opcio)
{
case '1':
AddNewStudent(std::cout, std::cin, students);
break;
case 2:
EditSudent(std::cout, std::cin, students); // << queries student and edit that
break;
case 3:
PrintStudents(std::cout, students);
break;
case 4:
return 0;
}
}
}
Note how the tasks are very well delimited into their own function, this also helps finding bugs faster, as it makes the code easier to read and reason about (the famous divide and conquer strategy).
Having the students array (or list) as a single entity simplifies its management, no extra variable to keep up to date, etc...
In a more serious application, the input validation would be best done using a template, and would give the user an escape character so he could cancel adding the new student at any time.

C++ need help, random switch statements [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 5 years ago.
Improve this question
I'm writing a code which is kind of like a fortune teller but I'm having some trouble with my switch statements. When executed the code prints out the same message and doesn't pick a random case like its supposed to! can someone please help me! thank you!
heres my code
#include<iostream>
#include<time.h>
#include<stdlib.h>
using namespace std;
void printGreeting(); // function prototype
int main()
{
int choice;
printGreeting();
cout << "Would you like to see your fortune?" << endl;
cout << "Press 1 to see your fortune or 2 if you don't!" << endl;
cin >> choice;
if (choice == 1)
{
cout << "Great! Your fortune is: ";
// Function to generate random number
void rand1();
srand(time(NULL));
int MAX_NUM;
MAX_NUM = 5;
int random = rand() % MAX_NUM;
cout << random << endl;
int selection;
selection = 5;
switch (selection)
{
case 1:
cout << "Change can hurt, but it leads a path to something better!";
break;
case 2:
cout << "If you have something good in your life don't let it go!";
break;
case 3:
cout << "You're in for a treat today.";
break;
case 4:
cout << "Land is always on the mind of a flying bird";
break;
case 5:
cout << "A dream you have will come true";
break;
}
return 0;
}
else if (choice == 2)
{
cout << "Okay goodbye!" << endl;
}
}
// Prints greeting message
void printGreeting() // function header
{
cout << "Hello! Welcome to your fortune teller!" << endl; // function body
}
Because selection = 5;
You want to choose selection with a random value between 1 - 5, right?
You switch by selection variable, which is explicitly set to 5 right before the switch itself. Consider switching by random variable.

Function running twice in console [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 7 years ago.
Improve this question
Basically, whenever I run this program in console to test it, my Menu() function gets called and when I give input, it prints the whole Menu() function again. Please help me fix this.
p.s. This is incomplete.
#include <iostream>
#include <windows.h>
using namespace std;
int Menu();
int main()
{
float currMoney = 0;
float giveMoney = 0;
float coke = 8.50;
float fantaG = 9;
float fantaO = 9;
float creamS = 7;
Menu();
int Choice = Menu();
system("cls");
if(Choice == 1)
{
cout<< "Insert R"<< coke << endl;
int pay = 0;
cin>> pay;
float returnA = pay - coke;
if(returnA < 0)
{
returnA = -returnA;
cout<< "you still owe R"<< returnA << "0" << endl;
}
}
}
int Menu()
{
cout<< "[Drink machine v1.0]\n\n"<< endl;
cout<< "[1]Coke -- R8,50"<< endl;
cout<< "[2]Fanta grape -- R9,00" <<endl;
cout<< "[3]Fanta orange -- R9,00"<< endl;
cout<< "[4]Cream Soda -- R7,00"<< endl;
int Choice = 0;
cin>> Choice;
return Choice;
}
The reason it's being called twice is because you're calling it twice!
Menu(); // first time
int Choice = Menu(); // second time
In the first call you don't capture the return value - so all it does it show the menu, ask for input, and then discard the result.
In the second call you show the menu again, ask for input, and then this time you capture the result, and action on that result.
From the look of it you want to remove the first call to Menu()
You are calling it twice in the code
int main() {
Menu();
int Choice = Menu();
}

C++ Text based game [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I am currently making a small console based text game in C++ with visual studio 2010.
I have encounted the problem of; when I get my name entered and difficulty selected I go to make the introductory text and I enter :
cout <<"Welcome "<<userName<<"... You are a lone: "<<pickRace<<" Your journey will be a "<<difficulty<<" one.";
And I want it to show up as : Welcome Blake... you are a lone Human/Orc your journey will be a easy/medium/hard one.
But I comes up as Welcome Blake... you are a lone 1/2 your jouney will be a 1/2/3 one.
this is a problem I think due to my switch's could anyone tell me how I need to rewrite them to get it appear with the name instead of numbers?
original code :
cout <<"Please pick your race: \n";
cout <<"1 - Human\n";
cout <<"2 - Orc\n";
int pickRace;
cout <<"Pick your race: ";
cin >>pickRace;
switch (pickRace)
{
case 1:
cout <<"You picked the Human race.\n";
break;
case 2:
cout <<"You Picked the Orc race\n";
break;
default:
cout <<"Error - Invalid imput; only 1 or 2 allowed.\n";
}
int difficulty;
cout <<"\nPick your level diffuculty: \n";
cout <<"1 - Easy\n";
cout <<"1 - Medium\n";
cout <<"3 - Hard\n";
cout <<"Pick your level difficulty: ";
cin >>difficulty;
switch (difficulty)
{
case 1:
cout <<"You picked Easy.\n\n";
break;
case 2:
cout <<"You picked Medium.\n\n";
break;
case 3:
cout <<"You picked Hard.\n\n";
break;
default:
cout <<"Error - Invalid imut; only 1,2 or 3 allowed.\n";
}
You are storing pickRace and difficulty as integers. Try doing something like:
int pickRace;
string raceText; //we will store the race type using this
cout <<"Pick your race: ";
cin >>pickRace;
switch (pickRace)
{
case 1:
cout <<"You picked the Human race.\n";
raceText = "Human";
break;
case 2:
cout <<"You Picked the Orc race\n";
raceText = "Orc";
break;
default:
cout <<"Error - Invalid imput; only 1 or 2 allowed.\n";
}
Note the raceText string variable.
Repeat this for difficulty.
Then use raceText and difficultyText to print your message:
out <<"Welcome "<<userName<<"... You are a lone: "<<raceText<<" Your journey will be a "<<difficultyText<<" one.";
Consider using enums and overload operator<< and operator>> for them:
#include <iostream>
#include <cassert>
enum difficulty { EASY = 1, MEDIUM = 2, HARD = 3 };
std::istream& operator>>( std::istream& is, difficulty& d )
{
int i;
is >> i;
assert( i > 0 && i < 4 ); // TODO: Use real error handling, throw an exception
d = difficulty( i );
return is;
}
std::ostream& operator<<( std::ostream& os, difficulty d )
{
switch( d ) {
case EASY: return os << "easy";
case MEDIUM: return os << "medium";
case HARD: return os << "hard";
}
return os << "unknown[" << (int)d << "]";
}
int main()
{
difficulty d;
std::cout << "Pick difficulty: 1-easy, 2-medium, 3-hard: ";
std::cin >> d;
std::cout << "You picked difficulty: " << d << std::endl;
}
Why do you expect it to print string when you are storing choices as ints...
You can use std::map
#include <map>
std::map<int, std::string> difficulty;
difficulty[1] = "easy";
difficulty[2] = "medium";
difficulty[3] = "hard";
int choice_difficulty;
std::cin>>choice_difficulty;
/*Check if user entered correct number*/
std::map<int, std::string>::iterator it = difficulty.find(choice_difficulty);
if(it == difficulty.end())
std::cout << "wrong choice";
cout <<"Welcome "<<userName<<" Your journey will be a "<<difficulty[choice_difficulty];
You may want to use lookup tables to convert between enums or numeric IDentifiers (IDs) and the text they represent.
For example:
struct Race_Text_Entry
{
const char * text;
unsigned int id;
};
static const Race_Text_Entry race_name_table[] =
{
{"Unknown", 0},
{"Human", ID_HUMAN_RACE},
{"Orc", ID_ORC_RACE},
{"Elf", ID_ELF_RACE},
};
static const unsigned int NUM_RACE_ENTRIES =
sizeof(race_name_table) / sizeof(race_name_table[0]);
std::string Race_ID_To_Text(unsigned int id)
{
unsigned int i = 0;
std::string race_name = "Race unknown";
for (i = 0; i < NUM_RACE_ENTRIES; ++i)
{
if (race_name_table[i].id == id)
{
race_name = race_name_table.text;
break;
}
}
return race_name;
}
int main(void)
{
std::cout << "My race: " << Race_ID_To_Text(ID_RACE_HUMAN) << "\n";
return 0;
}
A nice advantage to the constant lookup table as an array, is that it can be stored in the read-only data section of the program and loaded with the constant data. The initialization time is negligible compared with creating a std::map variable during initialization.
pickRace and difficulty are Integers. You're printing integers instead of the actual difficulty. You need to somehow logically represent the difficulty (and pickRace)