Queue using struct (Taxi dispatch problem) - c++

I want to write program that reads command from user, when d is entered a taxi is entered ,it prompts to enter driver_id and stores taxi in in queue (queue can have maximum n taxi), when command c is entered by customer it assigns the earliest taxi in the queue to the customer.
I'm trying to solve it using struct member function so that our code looks good, but although I have initialized n=4, it is only able to store 2 taxi, and shows me that the queue is full for the 3rd entry, which should not happen. Please review my approach.
Program run as such:
PS C:\Users; if ($?) { g++struct_taxi};; if ($?) { .\struct_taxi}
enter command:d
enter driverid:122
enter command:d
enter driverid:124
enter command:d
enter driverid:126
Q is full
Code:
#include<iostream>
using namespace std;
const int n=4;
struct Queue{
int elements[n],nwaiting,front;
void initialize(){
nwaiting=0;
front=0;
}
bool insert(int v){
if(nwaiting>=n)
return false;
elements[(front+nwaiting)%n]=v;
nwaiting++;
return true;
}
bool remove(int &v){
if(nwaiting==0)
return false;
else{
v=elements[front];
front=(front+1)%n;
nwaiting--;
return true;
}
}
};
int main(){
Queue q;
q.initialize();
while(true){
cout<<"enter command:";
char c;cin>>c;
if(c=='d'){
cout<<"enter driverid:";
int driverid;cin>>driverid;
if(!q.insert(driverid)){
cout<<"Q is full\n";}
else{
q.insert(driverid);
}
}
else if(c=='c'){
int driverid;
if(!q.remove(driverid)){
cout<<"No taxi available.\n";
}
else
//q.remove(driverid);
cout<<"assigning:"<<" "<<driverid<<endl;
}
}
}

The problem is that when you check the condition if(!q.insert(driverid)), you've already insert that driver into the system. Then the else statement insert it another time with q.insert(driverid);
So the solution is to simply remove the else statement.
#include<iostream>
using namespace std;
const int n=4;
struct Queue
{
int elements[n],nwaiting,front;
void initialize()
{
nwaiting=0;
front=0;
}
bool insert(int v)
{
if(nwaiting>=n) {return false;}
elements[(front+nwaiting)%n]=v;
nwaiting++;
return true;
}
bool remove(int &v)
{
if(nwaiting==0)
return false;
else
{
v=elements[front];
front=(front+1)%n;
nwaiting--;
return true;
}
}
};
int main()
{
Queue q;
q.initialize();
while(true)
{
cout<<"enter command:";
char c;
cin>>c;
if(c=='d')
{
cout<<"enter driverid:";
int driverid;
cin>>driverid;
if(!q.insert(driverid))
{
cout<<"Q is full\n";
}
}
else if(c=='c')
{
int driverid;
if(!q.remove(driverid))
{
cout<<"No taxi available.\n";
}
else {cout<<"assigning:"<<" "<<driverid<<endl;}
}
}
}
Result:
enter command:d
enter driverid:121
enter command:d
enter driverid:122
enter command:d
enter driverid:123
enter command:d
enter driverid:124
enter command:d
enter driverid:125
Q is full
An easier way obviously is to use std::queue, a data structure used for situation exactly like this, and as it came with the same functionality of your Queue struct, the code would be much shorter:
#include <iostream>
#include <queue>
using namespace std;
const int maxn=2;
int main()
{ queue<int> q;
while(true)
{
cout << "Enter command : "; char c; cin >> c;
if (c == 'd') //if inserting new driver
{
cout << "Enter driver's ID : "; int id; cin >> id; //input id
if (q.size() == maxn) {cout << "Queue is full\n";} //if size of queue is equal to maxn, no insert
else {q.push(id);} //else insert
}
else if (c == 'c')
{
if (q.empty()) {cout << "No driver available\n";} //if no driver, no assigning
else
{
int curDriver = q.front(); //take drive in front of queue
q.pop(); //take the driver id out of queue
cout << "Assigned driver : " << curDriver << "\n";
}
}
}
}
Result:
Enter command : d
Enter driver's ID : 123
Enter command : d
Enter driver's ID : 124
Enter command : d
Enter driver's ID : 125
Queue is full
Enter command : c
Assigned driver : 123
Enter command : c
Assigned driver : 124
Enter command : c
No driver available
Enter command :
Also, it's not recommended to use keywords like front, remove, etc... for variable names. And check out Why is "using namespace std;" considered bad practice?

Related

if else problem salary formula for loop desire loop user input

asking desire number to become the for loop(how many employee if input is 4 then 4 loop if 3 3 loops), salary formula not working, if else statement for string name to not accept number and vice versa integer to not accept letters. another one of my problem is how can I name the loop for example the question is name hours and rate then the cout should do 1. name hours rate, 2.name hours rate 3.name hours rate... the code is working.. just need some imporvements.
#include <iostream>
#include <cstdlib>
using namespace std;
void displayRules()
{
cout<<"====================="<<endl;
cout<<" EMPLOYEE-SALARY "<<endl;
cout<<"====================="<<endl;
cout<<" "<<endl;
}
int main()
{
char ans;
do
{
system("cls");
displayRules();
struct Employee
{
string name;
double hours;
double rate;
double salary;
Employee *next;
Employee *prev;
};
Employee *head;
head=NULL;
Employee *newEmployee;
Employee *EmpPointer;
Employee *nextEmpPointer;
Employee *prevEmpPointer;
string inpname;
int inpN;
double inphours;
double inprate;
double salary;
salary = (inprate*inphours);
for(int ctr=0; ctr<3; ctr++)
{
cout<<endl;
cout<<"Enter Name: \t\t";
cin>> inpname;
cout<<"Enter # Hours Worked: \t";
cin>> inphours;
if (inphours<0)
{
cout << "Invalid Input! Program Stopped. ";
return 0;
}
cout<<"Enter Rate per Hour: \t";
cin>> inprate;
if (inprate<0)
{
cout << "Invalid Input! Program Stopped. ";
return 0;
}
newEmployee = new Employee;
newEmployee->name=inpname;
newEmployee->hours=inphours;
newEmployee->rate=inprate;
newEmployee->next=NULL;
if (head==NULL)
head=newEmployee;
else
{
EmpPointer=head;
while (EmpPointer->next)
EmpPointer=EmpPointer->next;
EmpPointer->next=newEmployee;
}
}
cout<<endl;
Employee *displayPointer;
displayPointer=head;
system("cls");
cout<<"------------------------------------------------------------"<<endl;
cout<<" =Summary of PAYROLL= "<<endl;
cout<<"------------------------------------------------------------"<<endl;\
cout<<"Employee Name\t"<<"# Hours Worked\t"<<"Rate/Hour\t"<<"Salary\t"<<endl;
while (displayPointer)
{
cout<<displayPointer->name<<"\t\t";
cout<<displayPointer->hours<<"\t\t";
cout<<displayPointer->rate<<"\t\t";
cout<<displayPointer->salary<<endl;
displayPointer=displayPointer->next;
}
cout<<"------------------------------------------------------------"<<endl;
cout<<endl;
cout << "Would you like to run the program again? (Y/N) ";
cin>>ans;
}
while (ans == 'y' or ans == 'Y');
return 0;
}
Note: The salary wasn't being calculated so I fix that.
I broke your code into small functions in which each function only does one thing and one thing only (Single Responsibility Principle).
Also, I introduce function templates that allows you to reuse a function when you provide the type.
Finally, the code is missing a clean up of pointers to prevent memory leaks. Each time you use the keyword new to obtain a pointer to memory, you need later to check if the pointer contains null and if doesn't then use the keyword delete to free that memory, else you end with memory leaks in your code. Therefore, I leave you with the task to write the function that should iterate your employee list and free the memory to prevent memory leaks.
I hope this is useful.
#include <iostream>
#include <cstdlib>
using namespace std;
struct Employee {
string name;
double hours;
double rate;
double salary;
Employee *next;
Employee *prev;
};
void displayRules() {
cout<<"====================="<<endl;
cout<<" EMPLOYEE-SALARY "<<endl;
cout<<"====================="<<endl;
cout<<" "<<endl;
}
// Here we create a function template to make this code more reusable
template <typename T>
T consoleInput(const std::string& prompt) {
T value;
std::cout << prompt;
std::cin >> value;
return value;
}
// Lets create our own assert to exit the app.
void assertGreaterEqualThanZero(const double value, const std::string& prompt){
if (value < 0) {
cout << prompt;
exit(1);
}
}
// Small functions that do one thing only makes coding easy to debug
Employee* createEmployee(string name, int hours, int rate) {
Employee *newEmployee = new Employee;
newEmployee->name=name;
newEmployee->hours=hours;
newEmployee->rate=rate;
newEmployee->salary = (rate * hours);
newEmployee->next=NULL;
// You need to set and maintain ->prev
// if you are thinking on using a double linked list
// else remove it from the structure since is unused.
return newEmployee;
}
// This is a helper function to add new employees to a list
Employee* addToEmployeeList(Employee* list, Employee* newEmployee){
if (list==NULL) {
list = newEmployee;
} else {
Employee *EmpPointer = list;
while (EmpPointer->next)
EmpPointer=EmpPointer->next;
EmpPointer->next=newEmployee;
}
return list;
}
// The only purpose of this function is to print the list provided
void printEmployeList(Employee* employeeList){
Employee *currentEmployee = employeeList;
system("cls");
cout<<"------------------------------------------------------------"<<endl;
cout<<" =Summary of PAYROLL= "<<endl;
cout<<"------------------------------------------------------------"<<endl;
while (currentEmployee){
cout<<"Employee Name\t"<<"# Hours Worked\t"<<"Rate/Hour\t"<<"Salary\t"<<endl;
cout<<currentEmployee->name<<"\t\t";
cout<<currentEmployee->hours<<"\t\t";
cout<<currentEmployee->rate<<"\t\t";
cout<<currentEmployee->salary<<endl;
cout<<"------------------------------------------------------------"<<endl;
currentEmployee=currentEmployee->next;
}
}
// I leave you with this piece that is missing.
// TODO: create function that delete each employee in the list,
// then deletes the list in order to prevent memory leaks
int main() {
char ans;
do {
system("cls");
displayRules();
Employee *employeeList;
employeeList=NULL;
for(int ctr=0; ctr<3; ++ctr) {
// Lets declare and instantiate when we need it.
string name = consoleInput<string>("Enter Name: \t\t");
// No need to use inp (as inphours) in front of your variables
// It makes it harder to read. Just put hours as a name.
double hours = consoleInput<double>("Enter # Hours Worked: \t");
assertGreaterEqualThanZero(hours, "Invalid Input! Program Stopped.");
double rate = consoleInput<double>("Enter Rate per Hour: \t");
assertGreaterEqualThanZero(rate, "Invalid Input! Program Stopped. ");
Employee *newEmployee = createEmployee(name, hours, rate);
employeeList = addToEmployeeList(employeeList, newEmployee);
}
cout << endl;
printEmployeList(employeeList);
cout << "Would you like to run the program again? (Y/N) ";
cin>>ans;
} while (ans == 'y' or ans == 'Y');
return 0;
}

Whats a good way to get the program to end based on user input?

I did my "Hello World", I'm just getting started on my programming adventure with C++. Here is the first thing I've written, what are some ways to get it to end with user input? I'd like a yes or no option that would terminate the program. Also any feedback is welcome, thank you
#include <iostream>
using namespace std;
void Welcome();
void calculateNum();
void tryAgain();
int main() {
Welcome();
while (true) {
calculateNum();
tryAgain();
}
system("pause");
}
void calculateNum() {
float userNumber;
cin >> userNumber;
for (int i = 100; i >= 1; i--) {
float cNumber = i* userNumber;
cout << i << " >>>>> " << cNumber << endl;
}
}
void Welcome() {
cout << "Welcome \n Enter a number to see the first 100 multiples \n";
}
void tryAgain() {
cout << "Try again? Enter another number... ";
}
Here is one option:
Switch to do ... while loop, with the condition at the end.
Make your tryAgain() function return a boolean and put it in the while condition.
In tryAgain function read input from the user, and compare it to expected answers.
First, lets add a new header for string, it will make some things easier:
#include <string>
Second, lets rebuild the loop:
do {
calculateNum();
} while (tryAgain());
And finally, lets modify the function:
bool tryAgain() {
string answer;
cout << "Try again? (yes / no)\n";
cin >> answer;
if (answer == "yes") return true;
return false;
}
Now, there is a slightly shorter way to write that return, but it might be confusing for new learners:
return answer == "yes";
You don't need the if because == is an operator that returns bool type value.
You can change your calculateNum() in the following way:
Change the return value of your calculateNum() function into bool to indicate whether the program shall continue or stop
read the input into a std::string
check if the string is equal to your exit string like 'q' for quit
3.a in that case, your function returns false to indicate the caller that the program shall stop
3.b otherwise, create a stringstream with your string and read the content of the stream into your float variable and continue as you do like now
In your loop in your main function you break if calculateNum() returned false
Here is a simple solution:
#include <iostream>
// Here are two new Includes!
#include <sstream>
#include <string>
using namespace std;
void Welcome();
// Change return value of calculateNum()
bool calculateNum();
void tryAgain();
int main()
{
Welcome();
while (true)
{
if (!calculateNum())
break;
tryAgain();
}
system("pause");
}
bool calculateNum()
{
//Read input into string
string userInput;
cin >> userInput;
//Check for quit - string - here just simple q
if (userInput == "q")
return false;
//otherwise use a std::stringstream to read the string into a float as done before from cin.
float userNumber;
stringstream ss(userInput);
ss >> userNumber;
//and proces your numbers as before
for (int i = 100; i >= 1; i--)
{
float cNumber = i * userNumber;
cout << i << " >>>>> " << cNumber << endl;
}
return true;
}
void Welcome()
{
cout << "Welcome \n Enter a number to see the first 100 multiples \n";
}
void tryAgain()
{
cout << "Try again? Enter another number... ";
}
Having your users input in a string you can even do further checks like checking if the user entered a valid number, interpret localized numbers like . and , for decimal delimitters depending on your system settings and so on.

Need 'return to main menu' feature in my C++ code

I have created a C++ program. In this I have added many options for a user.
But in every choice I need to add a function from which a user can either choose to exit the program or can return to the main menu depending upon his choice. So can i have help in my coding.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-:
#include<iostream.h>
#include<conio.h>
void main()
clrscr();
int choice,p_card;
char text0,text1;
cout<<"\n\n\t\t\t \"Welcome to Zinc hospital\"\n\n\n";
cout<<"\tMENU\n";
cout<<"\n\n1. Emergency treatment\n\n";
cout<<"2. Common treatment\n\n";
cout<<"3. Regular checkups\n\n";
cout<<"4. Get appointment\n\n";
cout<<"5. Consult specialist\n\n";
cout<<"6. Pay due amount\n\n";
cout<<"7. Log in for new patient card\n\n";
cout<<"8. For suggestions, feedbacks and register complains\n\n";
cout<<"\n\t\t\t\t\t\t\t\tChoice______";
cin>>choice;
clrscr();
if(choice==1)
{
int e_choice;
cout<<"\n\n\n Enter the type of emergency";
cout<<"\n\n1. Accidental case";
cout<<"\n\n2. Heavy injury case";
cout<<"\n\n3. Delicate organ injury\n\n";
cout<<"4. Any other\n\n";
cout<<"\n\n\t\t\t\t\t\t\tEmergency choice____";
cin>>e_choice;
if(e_choice==4)
{
cout<<"Please specify the type of emergency ";
cin>>text0;
}
cout<<"\n\n\n\n\t\t\t \"EMERGENCY DECLARED\"\n\n\t \'Please quickly proceed to the operation theatre with patient\'";
}
if(choice==2)
{
cout<<"\n\nEnter the patient card number\n\n\t";
cout<<"\t\t\tCard No.______";
cin>>p_card;
cout<<"\n\n\t\t\tYour card has been recognized succesfully.";
cout<<"\n\n\nNow enter the specific treatment to be provided___";
cin>>text0;
cout<<"\n\n\n\n \t\t\tDATA recorded succesfully";
cout<<"\n\nYour card has been charged $10.\n\n\n\n Please proceed to counter to get the room no. and wait list serial.";
}
else if(choice==3)
{
cout<<"";//Under construction
}
else if(choice==4)
{
cout<<"";//Under construction
}
else if(choice==5)
{
cout<<"";//Under construction
}
else if(choice==6)
{
cout<<"";//Under construction
}
else if(choice==7)
{
cout<<"";//Under construction
}
else if(choice==8)
{
cout<<"";//Under construction
}
else if(choice!=1&&choice!=2&&choice!=3&&choice!=4&&choice!=5&&choice!=6&&choice!=7&&choice!=8)
{
cout<<"Invalid choice inputed";
cout<<"\n\n\n\n\n\n\t\t#Domain ERROR";
}
getch();
}
Lookup table (one of many solutions).
typedef (void) (P_Function)(void);
struct Menu_Entry
{
unsigned int selection_number;
const char * text;
P_Function p_processing_function;
};
void Process_Emergency_Treatment(void);
void Process_Common_Treatment(void);
Menu_Entry main_menu[] =
{
{1, "Emergency Treatment", Process_Emergency_Treatment},
{2, "Common Treatment", Process_Common_Treatment},
};
static const unsigned int quantity_menu_items =
sizeof(main_menu) / sizeof(main_menu[0]);
// ...
unsigned int selection;
std::cout << "Enter selection: ";
std::cin >> selection;
unsigned int index = 0U;
for (index = 0U; index < quantity_menu_items; ++index)
{
if (main_menu[index].selection_number == selection)
{
main_menu[index].p_processing_function(); // Execute the command processor.
break;
}
}
if (index >= quantity_menu_items)
{
std::cout << "\nInvalid selection, try again.\n";
}
A nice advantage to the lookup table is that when you want to add items to the menu, add an entry into table. Also, you only need to test the search loop once. Adding more entries to the table doesn't effect the execution of the search loop.
Edit 1: Fundamental menu algorithm
The fundamental algorithm can look like this:
bool selection_is_valid = false;
while (!selection_is_valid)
{
Print_Menu();
unsigned int selection = 0U;
std::cout << "Enter selection: ";
std::cin >> selection;
if (select >= MAXIMUM_CHOICES)
{
selection_is_valid = false;
}
else
{
Process_Menu_Item(selection);
selection_is_valid = true;
}
}
With a little skill you can modify the above algorithm to display until an "exist selection" is pressed.

Printing elements in a string list by index C++

Hi here is what I have so far. The operation printList(strList,indexList) will print the elements in strList that are in positions specified by indexList but im having trouble doing so. I'm trying to use the public STL container operations but having trouble. Any help would be great! Thank you!
#include<cstdlib>
#include<iostream>
#include<string>
#include<list>
using namespace std;
// PURPOSE: To have the user enter strings into list 'strList'. No return value.
void enterStringList(list<string>&strList){
while (true){
string entry;
cout << "Please enter a string or just press 'enter' to quit: ";
getline(cin, entry);
if (entry.empty())
break;
strList.push_back(entry);
}
}
void enterIntegerList(list<int>& intList, int limit) {
bool shouldContinue = true;
while (shouldContinue)
{
int number;
do
{
string entry;
cout << "Please enter an integer [0-"
<< limit
<< "], or just press 'enter' to quit: ";
getline(cin, entry);
if (entry.empty())
{
shouldContinue = false;
break;
}
number = atoi(entry.c_str());
} while ((number < 0) || (number > limit));
if (shouldContinue)
intList.push_back(number);
}
}
// PURPOSE: To print the elements in L that are in positions specified by P.
// No return value.
void printList(list<string>& strList, list<int>& indexList){
// HERE }
int main() {
list<string> strList;
list<int> indexList;
enterStringList(strList);
if (!strList.empty())
{
enterIntegerList(indexList, strList.size() - 1);
indexList.sort();
printList(strList, indexList);
}
return(EXIT_SUCCESS);}

How do I change the int variable in a cycle and if so is there a more efficient way?

First post ever on this site so spare my life , please.
I'm trying to do a little encryption and decryption program imitating the Enigma cipher/machine from the WW2 (enough history lessons)
So I'm trying to input a number and a letter like so : 1h 2e 3l 4l 5o ;
Because I don't use a cycle I need to write for every variable that I'm adding the number , but what do I do if I have less letters than variables?The only way I can think of is using a cycle which checks if the input is a letter or not.That's why the current code I've written only can be used for specific amount of numbers and letters...
#include <iostream>
#include <limits>
using namespace std;
int main()
{
int opt;
cout<<"Enter 1 for encryption and 2 for decryption. "<<endl;
cin>>opt;
if(opt == 1)
{
int setting1,setting2,setting3,setting4;
char a,b,c,d;
cout<<"_________________________________________________"<<endl;
cin>>setting1>>a>>setting2>>b>>setting3>>c>>setting4>>d;
a+=setting1;
b+=setting2;
c+=setting3;
d+=setting4;
cout<<(char)a<<" "<<(char)b<<" "<<(char)c<<" "<<(char)d<<endl;
}
if(opt == 2)
{
int setting1,setting2,setting3,setting4;
char a,b,c,d;
cout<<"_________________________________________________"<<endl;
cin>>setting1>>a>>setting2>>b>>setting3>>c>>setting4>>d;
a-=setting1;
b-=setting2;
c-=setting3;
d-=setting4;
cout<<(char)a<<(char)b<<(char)c<<(char)d<<endl;
}
if(opt !=1 && opt !=2)cout<<"ERROR!"<<endl;
std::cout << "Press ENTER to continue..."<<endl;
std::cin.ignore( std::numeric_limits<std::streamsize>::max(),'\n');
return 0;
}
Also I was told that the last 2 lines would prevent the .exec from closing after it's done doing it's thing.
I recommend inputting your data in loops (cycles). But before that is accomplished, I suggest using a structure (or class) with an overloaded stream extraction operator.
struct Number_Letter
{
int number;
char letter;
friend std::istream& operator>>(std::istream& inp, Number_Letter& nl);
};
std::istream& operator>>(std::istream& inp, Number_Letter& nl)
{
inp >> nl.number;
if (inp)
{
inp >> nl.letter;
if (!isalpha(nl.letter))
{
// Error recovery for not reading a letter
}
}
else
{
// Error recovery for failing to read number.
}
return inp;
}
Your input loop would be something like:
Number_Letter nl;
while (std::cin >> nl)
{
// process the data
}
For cryptography, you may want to keep the data as a string:
std::string message;
getline(cin, message);
for (unsigned int i = 0; i < message.length(); i += 2)
{
if (!isdigit(message[i]))
{
cerr << "Invalid message type at position " << i << endl;
break;
}
if (i + 1 > message.length())
{
cerr << "Missing letter at end of message.\n";
break;
}
if (!isalpha(message[i+1]))
{
cerr << "Invalid message type at position " << i << endl;
break;
}
}
It sounds like you're trying to check for an unknown sequence of character/integers and need a loop to do the check?
int opt;
cout<<"Enter 1 for encryption and 2 for decryption. "<<endl;
cin>>opt;
if(opt != 1 && opt != 2)
{
cout << "Error" << endl;
return -1;
}
int integer;
char character;
char again;
do
{
cout<<"_________________________________________________"<<endl;
cin>>integer>>character;
if(opt == 1) {
character+=integer;
} else if(opt == 2) {
character-=integer;
}
cout << character <<endl;
cout << "Again (Y)?: ";
cin>>again;
}while(again == 'Y' || again == 'y');
std::cout << "Press ENTER to continue..."<<endl;
std::cin.ignore( std::numeric_limits<std::streamsize>::max(),'\n');
return 0;