I wrote a certain method on how to access my fields in a class, but my teacher told me I should use an enum.
How can I re-write this code to use an enum and not use gotos?
void SetType() {
cout << "Book SetType" << endl;
Choice: cout << "Please Select from the list: \n "
<< "1- Technical literature \n "
<< "2- Fiction literature \n "
<< "3- Textbook" << endl;
int i;
cin >> i;
switch (i) {
case 1:
Type = "Technical literature";
break;
case 2:
Type = "Fiction literature";
break;
case 3:
Type = "Textbook";
break;
default:
cout << "Erorr you entered a wrong choice" << endl;
goto Choice;
}
}
just use loops instead of gotos of it is going to be a spaghetti code.
Enums are fine to does not care about the numbers for the defines, because they are incremented automatically if you add a new one.
#include <iostream>
#include <string>
void SetType();
using namespace std;
string Type;
int main()
{
SetType();
cout << "so you choose " << Type << endl;
return 0;
}
enum select
{
Technical_literature = 1,
Fiction_literature,
Textbook
};
void SetType() {
cout<<"Book SetType"<<endl;
while(1)
{
cout<<"Please Select from the list: \n 1- Technical literature \n 2- Fiction literature \n 3- Textbook"<<endl;
int i;
cin >> i;
switch(i) {
case Technical_literature:
Type="Technical literature";
return;
case Fiction_literature:
Type="Fiction literature";
return;
case Textbook:
Type="Textbook";
return;
default:
cout << "Erorr you entered a wrong choice" << endl;
}
}
}
Your teacher meant that instead of hardcoding constants all over the place you need to declare your i as enum.
enum some_type {
type_techlit=1, type_fiction, type_textbook
};
some_type i;
And then read up on enums.
Related
I am working on a little text based adventure game, the first project I've ever worked on for my own enjoyment, and have ran into a problem. I have got it to ask if you want to play, what your name will be and then the problem starts when you try to choose a race. It works just fine when the user types the first character but when they type the string it will skip past the gender, and class cin. Do I have to clear the cin? Or is my code just wrong?? Thanks for any help you can provide.
#include "pch.h"
#include <iostream>
#include <string>
#include <cctype>
#include <map>
using namespace std;
enum races { Human, Orc, Elf, Dwarf};
enum classes { Warrior, Mage, Archer, Assassin};
const std::map< char, string > race_map =
{ {'H', "human"}, {'O', "orc"}, {'E', "elf"}, {'D', "dwarf"} };
const std::map< char, string > class_map =
{ {'W', "warrior"}, {'M', "mage"}, {'Ar', "archer"}, {'A', "assassin"}
};
void gameIntro();
void gameStart();
void raceFunc(char race);
void playerClassFunc(char playerClass);
void gameIntro()
{
string playerName;
char race;
char sex;
char playerClass;
cout << "Enter your name: \n";
cin >> playerName;
cout << "\n";
cout << "Select a race (Human, Orc, Elf, Dwarf): \n";
cin >> race;
cout << "\n";
raceFunc(race);
cout << "Select Gender (M or F): \n";
cin >> sex;
cout << "\n";
cout << "Select a class (Warrior, Mage, Archer, Assassin): \n";
cin >> playerClass;
cout << "\n";
playerClassFunc(playerClass);
gameStart();
}
void raceFunc(char race)
{
race = toupper(race);
switch (race)
{
case 'H':
cout << "You chose Human!\n\n";
break;
case 'O':
cout << "You chose Orc!\n\n";
break;
case 'E':
cout << "You chose Elf!\n\n";
break;
case 'D':
cout << "You chose Dwarf!\n\n";
break;
default:
cout << "Please choose from the following. Program closing.\n";
system("pause");
exit(0);
}
}
void playerClassFunc(char playerClass)
{
playerClass = toupper(playerClass);
switch (playerClass)
{
case 'W':
cout << "You chose Warrior!\n";
break;
case 'M':
cout << "You chose Mage!\n";
break;
case 'Ar':
cout << "You chose Archer!\n";
break;
case 'A':
cout << "You chose Assassin!\n";
break;
default:
cout << "Please choose from the following. Program closing.\n";
system("pause");
exit(0);
}
}
void gameStart()
{
}
int main()
{
char answer;
cout << "Welcome to Dark Horse\n\n";
cout << "This is my fisrt ever actual program I made out of my own free
will lol.\n";
cout << "It is a Text-Based Adventure game. In this game you will make a
character,\n";
cout << "and explore the land of Spelet, battling enemies, leveling up,
getting loot,\n";
cout << "and learning skills! You do not need to capitalize anything but
your character\n";
cout << "name. If a question has (something like this) if you don't
enter whats inside\n";
cout << "the program will CLOSE, so please pay attention! Thank you for
trying it out!\n";
cout << "I really hope y'all enjoy it!\n\n";
do
{
cout << "Would you like to play?\n";
cin >> answer;
if (answer == 'Y')
{
gameIntro();
}
else if (answer == 'N')
{
system("pause");
return 0;
}
else if (answer != 'N' || 'Y' || 'exit')
{
cout << "Come on dog it's Y or N...yes or no...\n\n";
}
} while (answer == 'N' || 'Y');
system("pause");
return 0;
}
"cin, of class istream, is the standard input channel used for user input. This steam corresponds to C's stdin. Normally, this stream is connected to the keyboard by the operating system." (Josuttis, 2012, p. 745)
Josuttis, N. (2016). The C++ Standard Library: A Tutorial and Reference 2nd Edition: Addison-Wesley
The types are important.
char race;
std::cout << "Please enter your race:" << std::endl;
std::cin >> race;
If the user enters "Human", the standard input stream contains Human and the race variable now has the value H (of type char). The standard input stream now contains uman.
char gender;
std::cout << "Please enter your gender:" << std::endl;
std::cin >> gender;
Calling >> with std::cin gets another character from the standard input stream (in this case u) and stores it in gender. The standard input stream now contains man.
While it appears that the gender question was skipped, you can now see that this is not the case. The input stream still contains characters. If you look at your first screenshot you can see that "Mage" was selected. This is because the value of playerClass is m, the same m from when you entered human.
One way to remedy this is to use std::string instead of char to store the input. That way you have more flexibility in parsing what the user enters (e.g. you can allow for H or Human).
I'm creating a student data management program in C++ and the function to insert examination marks is buggy.
The code given below is enough to recreate the buggy part of the program.
I have tried to increase the size of sub[] to 16
I have tried to insert data one after the other instead of a loop
None of the above seem to solve the problem
Menu function:
char ch;
main_menu:
clrscr();
cout << "Press the key for your choice:\n";
cout << "D -> Edit details\n";
cout << "R -> Get result\n";
cout << "I -> Insert marks\n";
cout << "E -> Exit Program";
choice:
ch = getch();
switch(ch)
{
case 'd':
//edit_nam(); Ignore this one
goto main_menu;
break;
case 'i':
ins_mar();
goto main_menu;
break;
case 'r':
//get_res(); This one is not related to the problem
goto main_menu;
break;
case 'e':
break;
default:
goto choice;
}
Insert marks function:
for(int i = 0; i < 6; i++)
{
clrscr();
cout << "Enter details of subject:" << i + 1;
cout << "\nSubject name:";
cout << "\nMarks:";
gotoxy(14, 1);
cin.getline(student.marks[i].sub, 8);
gotoxy(7,2);
cin >> student.marks[i].mark;
(i != 5) ? cout << "\nPress any key to continue..." : cout << "\nPress any key to return to menu...";
getch();
}
Student structure:
struct stu
{
char name[20];
int ID;
int cls;
mar marks[6];
};
Marks structure:
struct mar
{
char sub[8];
float mark;
}
If the code was working fine, then it would ask the user to enter the marks for all six subjects, every time the function is called in one run.
However, It is not so. In the first time of function call, everything happens in the correct manner, but it does not ask for subject name after first subject in any of the other runs.
I am trying to add a percent sign directly after a users input (so that the user doesn't have to type the percent symbol). When I try this, it either goes to the next line or doesn't work at all.
What I want: _%
// the blank is for the user's input.
Sorry if this is messy, I'm not sure how to add c++ here.
Here are some things that I have attempted:
// used a percent as a variable:
const char percent = '%';
cout << "Enter the tax rate: " << percent; // obviously here the percent
symbol goes before the number.
double taxRate = 0.0;
cin >> taxRate >> percent; // here I tried adding it into the cin after the cin.
cin >> taxRate >> '%'; // here I tried adding the char itself, but yet another failed attempt...
So, is it even possible to do what I am wanting?
It is definitely possible, however iostream does not really provide a proper interface to perform it. Typically achieving greater control over console io requires use of some platform-specific functions. On Windows with VS this could be done with _getch like this:
#include <iostream>
#include <string>
#include <conio.h>
#include <iso646.h>
int main()
{
::std::string accum{};
bool loop{true};
do
{
char const c{static_cast<char>(::_getch())};
switch(c)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
{
// TODO limit accumullated chars count...
accum.push_back(c);
::std::cout << c << "%" "\b" << ::std::flush;
break;
}
case 'q':
{
loop = false;
accum.clear();
break;
}
case '\r': // Enter pressed
{
// TODO convert accumullated chars to number...
::std::cout << "\r" "Number set to " << accum << "%" "\r" "\n" << ::std::flush;
accum.clear();
break;
}
default: // Something else pressed.
{
loop = false;
accum.clear();
::std::cout << "\r" "oops!! " "\r" << ::std::flush;
break;
}
}
}
while(loop);
::std::cout << "done" << ::std::endl;
return(0);
}
I have been having the same prob but I found an alternative, it doesn't automatically put % sign but it can let you add the %sign right after the cin without messing up when you run the code :> this is my homework, hope it helps as an example:
enter image description here
and here's what the output looks like:enter image description here
//Program that computes the total amount of savings after being invested
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
int main()
{
char percent [1];
float IR, IRp, TC, P, I, A;
cout << "Investment Rate:" << setw(10) << left << "";
cin>> IR >> percent;
IRp = IR*.01;
cout << "Times Compounded: " <<setw(10)<<""; //TC
cin>> TC;
cout<<"Principal:" << setw(13) << right << "$"; //P
cin>> P;
A = P*(pow(1 + (IRp/TC), TC));
I=A-P;
cout<<"Interest: " <<setw(15)<<"$ " <<fixed<<setprecision(2)<<I<<endl;
cout<< "Amount in Savings:" <<setw(5)<<"$"<<fixed<<setprecision(2)<<A<<endl;
return 0;
As part of a school assignment, I need to build a modular calculator with at least four modules (getData, getInteger, processData, displayData) doing add/subtract/multiply/divide/modulus operations on two integers.
I'm getting pretty stumped on putting this thing together, and I think it's largely because I'm struggling to understand how inter-function calls work (e.g. one function sending information to another function).
I've got the getInteger function getting integer input from the user, and I'm using processdata(intA, intB); to send this to the processData(int, int) function; but my getData(int) function also needs to send an integer input to processData - however processData(select) isn't valid because it doesn't have enough arguments. (I don't really understand what this means)
This is probably a bit confusing, so I've got the whole (unfinished/wip/doesn't actually work) program here:
//calculator program
//4 modules required: getData, getInteger, processData, displayData
#include <iostream> //To input/output to the display (I think)
#include <conio.h> //For getch() at end of program
using namespace std;
//prototypes
void getInteger(int, int);
void getData(int);
void processData(int, int);
void displayData(); // haven't added anything yet
int main(){
//prevents window from immediately closing
getch();
return 0;
}
void getInteger(int, int) {
int intA, intB;
cout << "Please enter integer one: " << endl;
cin >> intA;
cout << "Please enter integer two: " << endl;
cin >> intB;
processData(intA, intB); //sends info to processData function
}
void getData(int) {
int select;
cout << "Available Functions" << endl;
cout << "1. Addition (+)" << endl;
cout << "2. Subtraction (-)" << endl;
cout << "3. Multiplication (*)" << endl;
cout << "4. Division (/)" << endl;
cout << "5. Modulus (%)" << endl;
cout << "Please type your selection (1-5): " << endl;
cin >> select;
if (select > 5 || select < 1) {
cout << "Error: Out of Bounds, please re-enter your selection: " << endl;
cin >> select;
}
processData(select); //sends info to processData function
}
void processData() {
int add, sub, mul, div, mod, select, intA, intB;
switch(select) {
case 1:
select = 1; //addition
add = (intA + intB);
displayData(add); //sends info to displayData function
break;
case 2:
select = 2; //subtraction
sub = (intA - intB);
displayData(sub);
break;
case 3:
select = 3; //multiplication
mul = (intA * int B);
displayData(mul);
break;
case 4:
select = 4; //division
div = (intA / intB);
displayData(div);
break;
case 5:
select = 5; //modulus
mod = (intA % intB);
displayData(mod);
break;
default:
cout << "There's been an error :(" << endl;
}
return 0;
}
void displayData() {
}
Am I doing this all backwards? I feel like it'd be a lot easier if I could contain this in fewer functions, but it's mandatory to keep it in (at least) 4.
Your declarations and definitions are not matching with the arguments that you are passing. i.e. void processData() is in your definition, but you declare it void processData(int, int);
The traditional approach for this problem is to collect all the data needed in some way, then call the function to do the work. For your case, you'd have to figure out the select value, and then the intA and intB values [1], then pass all three into processData.
The other opption is to chain the calls together, so ask for the select value first, then pass the select to the function that reads the data, and call the processData from there.
So you would end up with something like this:
void getInteger(int select)
{
cout << "Please enter integer one: " << endl;
cin >> intA;
cout << "Please enter integer two: " << endl;
cin >> intB;
processData(select, intA, intB);
}
void processData(int select, int intA, int intB)
{
... code goes here...
}
I'm intentionally NOT writing the complete code - the way to learn programming is to DO things for yourself. Copy-n-paste is something you probably already can do.
[1] This is a bit problematic, a function can only return one thing. Since you have two different values to return, that's not going to work. An experienced programmer would either use reference-arguments, or return a structure containing both values, but my guess is that's part of what you are learning in a future lesson, so let's skip that idea.
Here is a working version of your code... Take note of the changes and also take notice to the use of pointers in getInteger(int*,int*)
Hope this helps you out!
#include <iostream> //To input/output to the display (I think)
#include <conio.h> //For getch() at end of program
using namespace std;
//prototypes
void getInteger(int*,int*);
void getData();
void processData(int, int, int);
void displayData(int); // haven't added anything yet
int main(){
getData();
return 0;
}
void getInteger(int *ptrA, int* ptrB) {
*ptrA = 0; //safety
*ptrB = 0; //safety
int tempA = 0;
int tempB = 0;
cout << "Please enter integer one: " << endl;
cin >> tempA;
cout << "Please enter integer two: " << endl;
cin >> tempB;
*ptrA = tempA;
*ptrB = tempB;
}
void getData() {
int select = 100;
while(select != 0){
cout << "Available Functions" << endl;
cout << "0. Exit program" << endl;
cout << "1. Addition (+)" << endl;
cout << "2. Subtraction (-)" << endl;
cout << "3. Multiplication (*)" << endl;
cout << "4. Division (/)" << endl;
cout << "5. Modulus (%)" << endl;
cout << "Please type your selection (1-5): " << endl;
cin >> select;
if (select > 5 && select > 0) {
cout << "Error: Out of Bounds, please re-enter your selection: " << endl;
cin >> select;
}else if(select == 0){
break;
}
int intA, intB; //these are set in the following void
getInteger(&intA, &intB);
processData(intA, intB, select); //sends info to processData function
}
}
void processData(int intA, int intB, int select) {
int add, sub, mul, div, mod;
switch(select) {
case 1:
select = 1; //addition
add = (intA + intB);
displayData(add); //sends info to displayData function
break;
case 2:
select = 2; //subtraction
sub = (intA - intB);
displayData(sub);
break;
case 3:
select = 3; //multiplication
mul = (intA * intB);
displayData(mul);
break;
case 4:
select = 4; //division
div = (intA / intB);
displayData(div);
break;
case 5:
select = 5; //modulus
mod = (intA % intB);
displayData(mod);
break;
default:
cout << "There's been an error :(" << endl;
}
// return 0; void does not return
}
void displayData(int result){
cout << "The result is: " << result << endl;
}
#include <iostream>
using namespace std;
void playgame ()
{}
void loadgame ()
{}
void playmultiplayer ()
{}
int main ()
{
int input;
cout << "1. Play game\n";
cout << "2. Load game\n";
cout << "3. Play multiplayer\n";
cout << "4. Exit\n";
cout << "Selection: ";
cin >> input;
switch ( input )
{
case 1: // Note the colon after each case, not a semicolon
playgame();
break;
case 2:
loadgame();
break;
case 3:
playmultiplayer();
break;
case 4:
cout << "Thank you for playing!\n";
break;
default: // Note the colon for default, not a semicolon
cout << "Error, bad input, quitting\n";
break;
}
}
This code is from the book I am currently studying, "jumping into c++" to describle the working of switch.
the author said " one issue you might notice is that the user gets only a single choice before the program exists. We can use while loop to around the switch block to solve the issue".
my question is - How can we use while loop to solve the issue? I tried a lot but am unable to do it.
Thanks.
You can do it like this using a do { ... } while() loop construct.
do {
if(cin >> input) {
// your switch
switch(input) {
case 1:
break; //
// so on
case 4:
cout << "Thank You!" << std::endl;
break;
}
} else {
// io error
break;
}
} while (input != 4);
I'd like to point out that your book probably sucks. Reading from a stream without checking the return value is just plain bad code. My code checks if the formatted input function actually extract output.
You can put the code in a do while loop and instead of exiting in the case 4,u can have the exit condition defined in the while condition.This way the user gets the option until he chooses 4
I guess the book will show examples of loops in the next chapter or so.
To answer your question: (as endless loop)
while(true)
{
//your code starting with cout ... ending with the closing } othe switch
}
#include <iostream>
using namespace std;
void playgame ()
{}
void loadgame ()
{}
void playmultiplayer ()
{}
int main ()
{
int input;
while(1)
{
cout << "1. Play game\n";
cout << "2. Load game\n";
cout << "3. Play multiplayer\n";
cout << "4. Exit\n";
cout << "Selection: ";
cin >> input;
switch ( input )
{
case 1: // Note the colon after each case, not a semicolon
playgame();
break;
case 2:
loadgame();
break;
case 3:
playmultiplayer();
break;
case 4:
cout << "Thank you for playing!\n";
exit(1);
break;
default: // Note the colon for default, not a semicolon
cout << "Error, bad input, quitting\n";
break;
}
}
}
You could wrap everything inside main() inside the following:
bool quit = false;
while(!quit)
{
//your code
}
And for cases 4 and 5, add
quit = true;
before break;