I have been working on an exercise in my c++ programming book and it basically is asking me to create a program that will take 3 files, an old master file of client data (account, name, balance), a transaction file (of account names and credits or debits), and then a function to merge this files and output a new master file of client data. I am pretty sure I know how to do this, or even if I don't I think I can figure it out, the problem I am having is with a simple choice selection interface which is implemented exactly the same as another program that works just fine. When I first run the program it will let me input a choice (int) and then run the appropriate function (of which I only have 1 implemented completely, that being the createMasterFile function. After creating entries in the file and having them read back to the screen just for debugging and verification purposees, it will return to the while statement below but if I watch the choice function in both the main function and the enterChoice() function when I make the first selection (the one that works) those variables (according to gdb) do not take on any values until AFTER createMasterFile runs, before that it states that it is not in scope, after it runs through once choice will take on the original value 1 as it hits while, then seems to skip the condition of the while statement, then hits the switch statement which somehow changes choice to 0 which then hits the default case which then returns to the while statement and choice takes on a value of 32767 and again seems to skip the conditional part of the while statement and gets stuck in an infinite loop at this point with choice never changing in value. In a very similar program (the only difference is that the program that works uses binary files instead of sequential files) this works just fine. The interface looks like this:
enum Choices {CREATE_MASTER =1, CREATE_TRANSACTION, SORT_MASTER, UPDATE_MASTER, SORT_TRANS, UPDATE_TRANS, MERGE, END };
int choice;
while ( ( choice = enterChoice()) != END )
{
switch( choice )
{
case CREATE_MASTER:
createMasterFile( inOutOldMasterFile );
break;
case CREATE_TRANSACTION:
break;
case SORT_MASTER:
break;
case UPDATE_MASTER:
break;
case SORT_TRANS:
break;
case UPDATE_TRANS:
break;
case MERGE:
break;
default:
cerr << "Incorrect choice" << endl;
break;
}
}
and the enterchoice() function is:
int enterChoice()
{
cout << "\nEnter your choice below" << endl
<< "1 - Create Master Record" << endl
<< "2 - Create Transaction Record" << endl
<< "3 - Sort Master File In Descending Order" << endl
<< "4 - Update Master File" << endl
<< "5 - Sort Transaction File" << endl
<< "6 - Update Transaction File" << endl
<< "7 - Merge Transaction and Old Master File" << endl
<< "8 - End Program\n?";
int choice;
cin >> choice;
return choice;
}
If you need to see all the code (just for clarity) here it is (for the functions that are currently being used)
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <cstdlib>
using namespace std;
void outputLine( int, const string, double );
void createMasterFile( fstream & );
int numberOfAccounts = 0;
void swap(int * const, int * const);
void swap( string * const, string * const);
void swap( double * const, double * const);
bool descending( int, int);
void sortAccounts(int, fstream &, bool (*)(int, int));
int enterChoice();
int main()
{
// create a fstream object for input and output to be passed to
// the functions that need to manipulate it.
fstream inOutOldMasterFile( "oldmaster.dat", ios::in | ios::out );
fstream inOutTransaction( "trans.dat", ios::in | ios::out );
ofstream outNewMaster( "newmaster.dat", ios::out);
enum Choices {CREATE_MASTER =1, CREATE_TRANSACTION, SORT_MASTER, UPDATE_MASTER, SORT_TRANS, UPDATE_TRANS, MERGE, END };
int choice;
while ( ( choice = enterChoice()) != END )
{
switch( choice )
{
case CREATE_MASTER:
createMasterFile( inOutOldMasterFile );
break;
case CREATE_TRANSACTION:
break;
case SORT_MASTER:
break;
case UPDATE_MASTER:
break;
case SORT_TRANS:
break;
case UPDATE_TRANS:
break;
case MERGE:
break;
default:
cerr << "Incorrect choice" << endl;
break;
}
}
return 0;
}
int enterChoice()
{
cout << "\nEnter your choice below" << endl
<< "1 - Create Master Record" << endl
<< "2 - Create Transaction Record" << endl
<< "3 - Sort Master File In Descending Order" << endl
<< "4 - Update Master File" << endl
<< "5 - Sort Transaction File" << endl
<< "6 - Update Transaction File" << endl
<< "7 - Merge Transaction and Old Master File" << endl
<< "8 - End Program\n?";
int choice;
cin >> choice;
return choice;
}
void createMasterFile( fstream &clientFile )
{
if(!clientFile)
{
clientFile.open("oldmaster.dat", ios::in | ios::out);
}
cout << "Enter the account, name and balance." << endl
<< "Enter end-of-file to end input (^d)\n? ";
int account;
string name;
double balance;
clientFile.seekp( 0, ios::beg );
// read account, name and balance from cin then place in file
while (cin >> account >> name >> balance )
{
numberOfAccounts++;
clientFile << account << ' ' << name << ' ' << balance << endl;
cout << "?";
} //end while
clientFile.seekg( 0, ios::beg );
cout << left << setw(10) << "Account" << setw(13)
<< "Name" << "Balance" << endl << fixed << showpoint;
while( clientFile >> account >> name >> balance)
{
outputLine( account, name, balance );
}
clientFile.close();
}
If this is really obvious I am sorry but I have tried to find some answer for almost 2 days now searching online.
Thanks in advance.
-Bobby
It seems your createMasterFile() reads from std::cin until std::cin goes into failure mode, e.g., because a wrong value was encountered or std::cin reached its end. This function correctly checks the input after reading.
After that, your enterChoice() function is entered without first clearing the failure setting for std::cin and this function doesn't check whether the read is actually successful and it won't because the stream is already in failure mode. The function should probably read the value and return a result something like this:
std::cin >> choice;
return std::cin? choice: ERROR;
Since createMasterFile() clearly leaves std::cin in failure mode, you should probably reset its state before trying to read your choice and probably also ignore the rest of the current line:
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Of course, if there is no further input from std::cin, reading a choice will still fail.
Related
So im trying to run a program that receives a set data from a file that updates each time the program is run and new data is added. But when i try to run it the program terminates after trying to receive input from user.The full code is as follow, im using devc++ if that matters
#include<iostream>
#include<fstream>
#include<string.h>
using namespace std;
struct Deets
{
string NameSite[];
string AddressName[];
int numVaccine[];
int numStall[];
string DateVax[];
string ContNum[];
};
void Outputmenu();
int AddData(int,struct Deets V);
void EditData(int,struct Deets V);
void ShowExisting(int,struct Deets V);
void ClearArr(int,struct Deets V);
int main()
{
int i;
ifstream r("Total.txt");
r>>i;
r.close();
Deets V;
ifstream a;
a.open("Data.txt");
for(int c=0;c<=i;c++)
while(a>>V.NameSite[c]>>V.AddressName[c]>>V.numVaccine[c]>>V.numStall[c]>>V.DateVax[c]>>V.ContNum[c]);
a.close();
int menuS;
do
{
Outputmenu();
cout<<"\nPlease choose from 1-4, press 0 to close menu"<<endl;
cin>>menuS;
if (menuS==1)
AddData(i,V);
else if (menuS==2)
EditData(i,V);
else if (menuS==3)
ShowExisting(i,V);
else if (menuS==0)
cout<<"Thank you for your cooperation, We hope to see you soon! \nClosing program..,";
else
cout<<"Error, not within selection"<<endl;
}
while (menuS!=0);
ofstream b("Data.txt");
for(int c=0;c<=i;c++)
while(b<<V.NameSite[c]<<" "<<V.AddressName[c]<<" "<<V.numVaccine[c]<<" "<<V.numStall[c]<<" "<<V.DateVax[c]<<" "<<V.ContNum[c]<<endl);
return 0;
}
void Outputmenu() //instruction about the command for the user
{
cout << " -hello there!- " << endl;
cout << "===================================================================" << endl;
cout << " ***PLEASE CHOOSE ONE OF THE OPTION BELOW*** " << endl;
cout << "===================================================================" << endl;
cout << "\t1. Add Data (about Vaccination Center)" << endl;
cout << "\t2. Edit Data" << endl;
cout << "\t3. Show Existing Data" << endl;
cout << "\t0. Close Program" << endl;
cout << "===================================================================" << endl;
}
int AddData(int c, struct Deets A)
{
bool rq;
int i = c;
cout<<"Enter your company name/ institute name : ";
cin.ignore();
getline(cin,A.NameSite[i]);
cout<<"\n\t\t Safety Measure"<<endl;
cout<<"-Maintain a distance of 1 meter between one other access to vaccine doses.\n"<<"-Have a dedicated toilets for patient\n"<<"-Ability to maintain room temperature between 19 – 25 degrees \n"<<"-Have an adequate place for patients to wait "<<"\n-Have adequate sharps disposal bins, appropriate for the volume of patients, and securely placed and spaced to mitigate the risk of needle stick injuries."<<endl;
cout<<"-Adequate handwashing facilities for staff, and antimicrobial hand sanitizers available.\n"<<"-Store and handle COVID-19 vaccines under proper conditions, including maintaining cold chain conditions and chain of custody at all times in accordance with a EUA or vaccine package insert, manufacturer guidance, and CDC guidance in the Vaccine Storage and Handling Toolkit."<<endl;
cout<<"-Appropriate security provisions to ensure no unauthorized access to vaccine doses."<<endl;
cout<<"\nAre all requirement met? \n1:Yes \n0:No"<<endl;
cin>>rq;
if(rq == 1)
{
cout<<"\nWhere is the location : "<<endl;
cin>>A.AddressName[i];
cout<<"How many vaccines required : "<<endl;
cin>>A.numVaccine[i];
cout<<"How many vaccine stall can a site hold : "<<endl;
cin>>A.numStall[i];
cin.ignore();
cout<<"Date for vaccine to be distributed"<<endl;
getline(cin,A.DateVax[i]);
cin.ignore();
cout<<"Enter your management contact number : "<<endl;
getline(cin,A.ContNum[i]);
cout<<"Certificate for "<<A.NameSite[i]<<endl;
i++;
}
else
{
cout<<"Thanks for the thought. We hope to cooperate with "<<(A.NameSite[i])<<" in the near future\n\n"<<endl;
if(i>0)
{
i = i-1;
}
else
{
i = 0;
}
}
return i;
}
void EditData(int i,struct Deets A)
{
int c,EN,edit=0;
for (int c=0;c<i;c++) //showing all Company/Institute name data
{
cout << c+1 << ". "<<A.NameSite[c]<<endl;
}
cout << "Enter number you would like to edit : "; //asking user to enter which data user want to edit
cin >> EN; //user enter which data they want to edit
c=EN-1;
cout << A.NameSite[c] << "\n" << "Do you want to edit this data? Yes:1 No:0"<<endl; //asking user whether they want to edit Company/Institute name
cin >> edit;
if(edit ==1) //if true, it will change the data
cin >> A.NameSite[c];
cout <<"Total stall : "<< A.numStall[c] << "\n" << "Do you want to edit this data? Yes:1 No:0"<<endl; //asking user whether they want to edit total Company/Institute vaccine stall
cin >> edit;
if(edit ==1) //if true, it will change the data
cin >> A.numStall[c];
cout <<"Adress : " << A.AddressName[c] << "\n" << "Do you want to edit this data? Yes:1 No:0"<<endl; //asking user whether they want to edit Company/Institute's address
cin >> edit;
if(edit ==1) //if true, it will change the data
cin >> A.AddressName[c];
cout << "Contact number : " << A.ContNum[c] << "\n" << "Do you want to edit this data? Yes:1 No:0"<<endl; //asking user whether they want to edit Company/Institute's contact number
cin >> edit;
if(edit ==1) //if true, it will change the data
cin >> A.ContNum[c];
cout << "Total Vaccine : "<< A.numVaccine[c] << "\n" << "Do you want to edit this data? Yes:1 No:0"<<endl; //asking user whether they want to edit total Company/Institute vaccine needed
cin >> edit;
if(edit ==1) //if true, it will change the data
cin >> A.numVaccine[c];
cout << "Date of vaccine : "<< A.DateVax[c]<< "\n" << "Do you want to edit this data? Yes:1 No:0"<<endl; //asking user whether they want to edit Company/Institute's receiving vaccine date
cin >> edit;
if(edit ==1) //if true, it will change the data
cin >> A.DateVax[c];
}
void ShowExisting(int i, struct Deets A) // void of ShowExisting that show the existing data stored in the program
{
for(int c=0; c<i; c++) //array to show all the existing data in the program so far
{
cout << (c+1) << ". "<< endl; //number that show the count of which set of data shown
cout << "Site Name: " << A.NameSite[c] << endl; //show the name of site in appropriate array of turn c
cout << "Address: " << A.AddressName[c] << endl; //show the address of site in appropriate array of turn c
cout << "Amount Vaccine: " << A.numVaccine[c]<< endl; //show the amount of vaccine needed in site in appropriate array of turn c
cout << "Amount Stall: " << A.numStall[c] << endl; //show the amount of stall needed in appropriate array of turn c
cout << "Vaccination Date: " << A.DateVax[c] << endl; //show the vaccination date in appropriate array of turn c
cout << "Contact Num.: " << A.ContNum[c] << "\n" << endl; //show the contact number of the reprsentative from the site in appropriate array of turn c
}
}
The program runs until input when there is no data in the file but when there is data, the program wont even go past
for(int c=0;c<=i;c++)
while(a>>V.NameSite[c]>>V.AddressName[c]>>V.numVaccine[c]>>V.numStall[c]>>V.DateVax[c]>>V.ContNum[c]);
please help as my caffeine brain is fried
*After considering everyone's response ive decided to rework the basis of the program with what everyone taught, Thank you for those who responded
IMHO, I would rewrite/redesign your code rather than debug it.
Let's start by differentiating a single Deet from a container of Deet:
struct Deet
{
string NameSite;
string AddressName;
int numVaccine;
int numStall;
string DateVax;
string ContNum;
};
You can then overload operator>>:
struct Deet
{
//...
friend std::istream& operator>>(std::istream& input, Deet& d);
};
std::istream& operator>>(std::istream& input, Deet& d)
{
std::getline(input, d.NameSite);
std::getline(input, d.AddressName);
input >> d.numVaccine;
input >> d.numStall;
std::getline(input, d.DateVax);
std::getline(input, d.ContNum);
return input;
}
You could declare a container and input the container like so:
std::vector<Deet> deet_container;
Deet d;
while (input_file >> d)
{
deet_container.push_back(d);
}
BTW, you should always put descriptive variables inside your function declarations. This gives people a better understanding of what the variables are and their positions.
Your function declarations could change:
typedef std::vector<Deet> Deet_Vector;
int AddData(int, Deet_Vector& V);
void EditData(int, Deet_Vector& V);
void ShowExisting(int, Deet_Vector& V);
void ClearArr(int, Deet_Vector& V);
By looking at AddData, the usage of the int first parameter is ambiguous.
Are you adding an int to the container?
Is the int the quantities of items to add to the container?
Likewise with the other functions.
Next, I would add one function at a time to the program, compile and debug, then add another, repeat.
BTW, you can simplify your Outputmenu function:
void Outputmenu()
{
static const char menu_text[] =
" -hello there!-\n"
"===========================================================\n"
" ***PLEASE CHOOSE ONE OF THE OPTION BELOW***\n"
"===========================================================\n"
"\t1. Add Data (about Vaccination Center)\n"
"\t2. Edit Data\n"
"\t3. Show Existing Data\n"
"\t0. Close Program\n"
"============================================================\n"
;
std::cout.write(menu_text, sizeof(menu_text);
}
By using the write method, the text is written as a block and is usually a lot faster than using a lot of operator<<.
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 apologize if this is in the wrong place. I didn't really see an area where to post specific code problems.
I'm tasked by my professor to create a program that allows a user to insert, edit and print out a database of clients. I'm having a problem with one of my functions, it doesn't seem to be comparing something well. The function is the EditClient function on line 85, the logic problem I'm having is on line 93. I included a few tests in the code that makes me certain it is line 93, for example in the else statement on line 99 I have it printing out the same arguments being used in the comparison. Which works! I'm clueless as to why it's not understanding the comparison.
#include <iostream>
#include <iomanip>
using namespace std;
struct ClientInfo{ // the structure template for the client info
char name[40]; //client name
char state[40]; //client state
char city[40];
int PhoneNumber;
long double AccountBalance; //accounts balance
char PaymentDate; //payment date
};
ClientInfo ClientList[10]; //intializes an array with the data type clientinfo
void MainMenu();
void NewClient(ClientInfo List[]); // prototypes
void ViewClient(ClientInfo List[]);
void EditClient(ClientInfo List[]);
int main(){
MainMenu();
system("pause");
}
void MainMenu(){ //this function is the main menu function
char choice = 4;
bool loop = true;
while (loop){
cout << "Welcome to the client database, enter 1 to view the clients, 2 to edit a client , and 3 to enter an entire new client. 0 to quit" << endl; //main menu prompt
cin >> choice;
if (choice == '1'){
ViewClient(ClientList);
}
else if (choice == '2'){
EditClient(ClientList);
}
else if (choice == '3'){
NewClient(ClientList);
}
else if (choice == '0'){
cout << "thank you for using the client database, closing out now" << endl;
loop = false;
}
else{
cout << "invalid number" << endl;
}
}
}
void NewClient(ClientInfo List[]){//function that goes through cins to insert client data
int desiredTimes = 0; // the number of clients the person wish to enter
cout << "how many clients are you entering ?, your list current has "<<endl;
cin >> desiredTimes;
cout << "entering new client function..." << endl;
for (int cnt = 0; cnt < desiredTimes; cnt++){ // runs the program exactly the amount of times the person wished.
cout << "please enter client name" << endl;
cin.ignore();
cin.getline(List[cnt].name, 40);
cout << "please enter client state" << endl; // the getline is used here because there may be spacings within these first 3 catagories
cin.getline(List[cnt].state, 40);
cout << "please enter client city" << endl;
cin.getline(List[cnt].city, 40);
cout << "please enter client Phone Number" << endl;
cin.ignore(); // this is used to prevent the getline from causing issues with the cin
cin >> List[cnt].PhoneNumber;
cout << "please enter client Account Balance" << endl;
cin >> List[cnt].AccountBalance;
cout << "please enter client Payment Date" << endl;
cin >> List[cnt].PaymentDate;
}
}
void EditClient(ClientInfo List[]){ // function to search for a name requested and display the info
char name[40];
cout << "what is the name of the client you wish to view (be specific)?";
cin >> name;
bool loop = true; // boolean for the loop
int cnt = 0; // position in the array
while (loop){
if (cnt < 11){
if (name == List[cnt].name){ //if true, prints out the client's info
cout << "true";
/*NewClient(List[cnt]);*/
loop = false; // ends the loop
}
else{
cout << name << " " << List[cnt].name << endl;
cnt++;
}
}
else{
cout << "your client isn't in the database M8" << endl;
loop = false;
}
}
}
void ViewClient(ClientInfo List[]){//this function goes through the client list and displays a particular client
cout << "the following is a huge overrun of all the data inside this list, prepare your self." << endl;
for (int cnt = 0; cnt <= 10; cnt++){//goes through until the counter is greater than the size of the list in the parameter
cout << endl;
cout << List[cnt].name;
cout << List[cnt].state;
cout << List[cnt].city;
cout << List[cnt].PhoneNumber;
cout << List[cnt].AccountBalance;
cout << List[cnt].PaymentDate;
}
}
this is the specific line, where i'm having a comparision error.
if (name == List[cnt].name){ //if true, prints out the client's info
if (name == List[cnt].name) is doing a pointer comparison, not a string comparison. This will only be true if name and List[cnt].name point to the same memory location, which they never will. You should probably be using std::string instead of char[], but if you need to use char[] for some reason, you'll need to use the strcmp() function to compare them.
instead of the if statement you are using, trying using this statement,
if (strcmp(name,List[cnt].name)==0){
It should work properly :)
The purpose of the conditional statement is to print out a simple text based menu and then store input from the user as well as evaluate this to the condition of a loop.
If the condition was not meet, the user should be prompted to enter in a int number, that would result in the condition being true. Instead it just exits the loop.
I have tried both while and now, if loops to accomplish the task.
Here is the Code:
#include "stdafx.h"
// Namespaces
using std::cin;
using std::cout;
using std::endl;
using std::istream;
using std::iostream;
using std::ostream;
using std::string;
// Variables
const string new_game = "Start a new game";
const string continue_game = "Continue your game";
const string load_save = "Load a save";
int menu_choice = 0;
const string choice_description = "You choice to";
// MAIN Program
int _tmain(int argc, _TCHAR* argv[])
{
cout << "Welcome to The Forgotten Time" <<endl;
cout << "You have the following options" << endl;
while (menu_choice < 1 || menu_choice > 3 )
{
cout << "1." << new_game << endl;
cout << "2." << continue_game << endl;
cout << "3." << load_save << endl;
cin >> menu_choice;
}
switch (menu_choice)
{
case 1: cout << choice_description << new_game;
case 2: cout << choice_description << continue_game;
case 3: cout << choice_description << choice_description;
}
cin.ignore();
cin.get();
return 0;
}
In the end i would like to be able to combine the conditional statement in a function
and pass it through a switch statement in order to create a sentence, that evaluates the
users input and displays their choice.
Initially you set:
int menu_choice = 0;
Then you ask:
if (menu_choice < 1 || menu_choice > 4 )
The choice is smaller than 1 so the if block is entered.
You then get some user input and exit the application.
You have no loop in your code at all. Just an initial conditional statement that would return a true value because:
menu_choice=0;
and,
if(menu_choice<1 ||...)
You don't need a "return" statement, either. Put in a switch() after your if().
Also, you could just remove the second if() condition and put your whole main() content in a while() or do..while() loop.
Also, a switch is pretty efficient if you have a menu based display that takes in certain specific discrete-set of values.
Remove your if condition, instead use a do while loop.
do{
cout << "1." << new_game << endl;
cout << "2." << continue_game << endl;
cout << "3." << load_save << endl;
cin >> menu_choice;
}
while (menu_choice!=0);
How to input a string of charaters like "Peter Johnson"?
My program only reads 1 single name, if I put a space, the program loops infinitely
Writting John, works, but the space character makes it loop. Why is that? Also I know the program might not be completely finished.
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
int x=0;
char name [25];
float paycheck;
cout<<"WELCOME TO THE EMPLOYEE SALARY GENERATION PROGRAM\n\n";
while (x!=-1)
{
cout<<"Enter employee name or -1 to stop the program\n";
cin>>name;
cout<<"Enter employee code (1=manager, 2=worker, 3=comission, 4=pieceworker) or -1 to stop the program\n";
cin>>x;
switch (x)
{
case 1:
cout<<"Your weekly total paycheck is 2 500 $\n"; // FIXED weekly manager's salary
break;
case 2: // 8.50 per hour + over time for workers
cout<<"Please enter the amount of hours worked\n";
cin>>paycheck;
if(paycheck<40)
paycheck=paycheck*8.50;
else
paycheck= (paycheck-40)*8.50 +(40*8.50);
cout<<name<<"'s paycheck is "<<paycheck<<"$\n";
break;
case 3: // comission workers make 250 + 5.7% of their weekly sales
cout<<"Please enter amount of weekly sale made\n";
cin>>paycheck;
paycheck = paycheck*5.7/100 + 250;
break;
case 4: // pieceworkers make 50$ per item produced
cout<<"Please enter the number of items produced this week\n";
cin>>paycheck;
paycheck = paycheck*50;
cout<<"The employee"<<name<<"Made"<<paycheck<<"$ this week";
break;
default:
break;
}
}
system ("PAUSE");
}
The 'cin' function stops reading when it finds a space. Use 'getline' to read the names.
EDIT: Debug the code, and added some safe measures to avoid program crashing due to bad input.
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
float foo()
{
float fl = 0.0f;
string str;
while(true) {
getline(cin, str);
stringstream sstream(str);
if (sstream >> fl)
break;
cout << "Invalid Input" << endl;
}
return fl;
}
int main()
{
string x;
string name;
char number = {0};
float paycheck;
cout << "WELCOME TO THE EMPLOYEE SALARY GENERATION PROGRAM" << endl << endl;
while (x!="-1") {
cout << "Enter employee name or -1 to stop the program" << endl;
getline(cin, name);
if (name == "-1") return 0;
cout<<"Enter employee code (1=manager, 2=worker, 3=comission, 4=pieceworker) or -1 to stop the program\n";
getline(cin, x);
if (x == "-1") return 0;
if (x.length() == 1)
number = x[0];
else {
cout << "Invalid Input" << endl;
continue;
}
switch (number) {
case '1':
cout << "Your weekly total paycheck is 2 500 $" << endl; // FIXED weekly manager's salary
break;
case '2': // 8.50 per hour + over time for workers
cout << "Please enter the amount of hours worked" << endl;
paycheck = foo();
if(paycheck<40)
paycheck=paycheck*8.50;
else
paycheck= (paycheck-40)*8.50 +(40*8.50);
cout << name << "'s paycheck is " << paycheck << "$" << endl;
break;
case '3': // comission workers make 250 + 5.7% of their weekly sales
cout << "Please enter amount of weekly sale made" << endl;
paycheck = foo();
paycheck = paycheck*5.7/100 + 250;
break;
case '4': // pieceworkers make 50$ per item produced
cout<<"Please enter the number of items produced this week" << endl;
paycheck = foo();
paycheck = paycheck*50;
cout<<"The employee " << name << " Made "<< paycheck << "$ this week" << endl;
break;
default:
cout << "Invalid Option." << endl;
break;
}
}
system ("PAUSE");
}
The main lesson to take away from this is: always check after reading that the read was successful! It wasn't don't proceed. In general, input looks something like this:
if (in >> var1 >> var2) { ... }
if (std::getline(in, string)) { ... }
... you'd use the input in the condition of a loop. Your main problems seem that the input for strings using in >> s first skips leading spaces and then reads non-space characters up to the first space (where space actually is any whitespace like space, newline, carriage return, form feed, backspace, etc.). If you want to read multiple words you'd need to determine how to best tell that reading should stop. For example you could read up to a specific character using std::getline(in, s, c) (where c defaults to \n if omitted).
If you try to read a value which can't be parsed successfully, e.g. when trying to read a number when the next non-space character isn't a digit, the stream will go into fail stated (i.e. its state gets the std::ios_base::failbit set) and it won't do anything useful until the state is clear()ed.
Use std::string
std::string myName;
std::getline(std::cin, myName);