Hey ! i am trying to create a program of hospital management system using doubly linked list in c++.
in this i am using whole class for patient data.
i created a nodes for linked list .
i am using one node to represent one bed in hospital.
but after that when i am trying to print some data manually , nothing is printing in console and program is ending without showing any output
this is my code :
#define max_limit 25;// maximum 50 beds can be there in hospital
using namespace std;
class patient //creating class to store the data of patient
{
public:
int pt_id;
string pt_name; //patient name
string diagnosis; //diagnosis patient have
};
struct bed //each bed in hospital
{
class patient p;
struct bed *prev;
struct bed *next;
};
int main()
{
//creating 3 beds in starting only and giving values.
struct bed *head=(struct bed *)malloc(sizeof(patient));
struct bed *second=(struct bed *)malloc(sizeof(patient));
struct bed *tail=(struct bed *)malloc(sizeof(patient));
head->prev=NULL;
head->p.pt_id=6478;
head->p.pt_name="Jayraj";
head->p.diagnosis="Headaches";
head->next=second;
second->prev=head;
second->p.pt_id=8933;
second->p.pt_name="Mayank";
second->p.diagnosis="Highfever";
second->next=tail;
tail->prev=second;
tail->p.pt_id=1788;
tail->p.pt_name="Jay";
tail->p.diagnosis="Stomacheache";
tail->next=NULL;
cout<<"Size:"<<sizeof(patient);
return 0;
}```
You should check the errors - make sure your environment displays them. There are at least these issues:
When allocating a bed you shouldn't use sizeof(patient), but sizeof(bed).
define should not end with a semi-colon.
As a bed could be empty, you'd better define the p member as a pointer to a patient instance
You're not using C++ syntax:
Use new instead of malloc.
Define constructors and methods
Use nullptr instead of NULL
Use PascalCase for class names
Here is some code for inspiration, but you'll need to add more logic to it for your assignment (e.g. you'll have to verify the limit of beds):
#define max_limit 25 // maximum 25 beds allowed in hospital
using namespace std;
class Patient
{
public:
int pt_id;
string pt_name; //patient name
string diagnosis; //diagnosis patient have
// Constructor:
Patient(int id, string name, string diag) :
pt_id(id), pt_name(name), diagnosis(diag) {}
};
class Bed
{
public:
Patient* p = nullptr;
Bed* prev = nullptr;
Bed* next = nullptr;
// Constructors:
Bed() {};
Bed(Patient* p) : p(p) {};
// Method to ease linking beds
Bed* prepend(Bed* other) {
other->next = this;
this->prev = other;
return other;
};
};
int main()
{
// Use constructor to create patients
Patient *jaray = new Patient(6478, "Jayraj", "Headaches");
Patient *mayank = new Patient(8933, "Mayank", "Highfever");
Patient *jay = new Patient(1788, "Jay", "Stomacheache");
// Use constructor and method to create linked list
Bed *beds = (new Bed(jay))
->prepend(new Bed(mayank))
->prepend(new Bed(jaray));
// Let's output something: the beds with patient names
Bed *bed = beds;
while (bed != nullptr) {
if (bed->p == nullptr) {
cout << "bed without patient\n";
} else {
cout << "bed occupied by " << bed->p->pt_name << "\n";
}
bed = bed->next;
}
return 0;
}
Related
I am trying to pass 5th element of an array(Products[]) of class product to another function. The goal is to update the information of the element Product[5]. Everything seems to work fine except information of Product[5] variable is not updating.
Update: Problem solved by removing while(!EOF), thanks to Remy Lebeau.
The relevant part of Class:
class product
{
private:
float Wholesale_Price = 0;
float Retail_Price = 0;
string Supplier = "N/A";
string Note = "N/A";
int Stock_Amount = 0;
public:
string Name="N/A";
void UpdateRetailPrice(float New_Retail_Price)
{
Retail_Price = New_Retail_Price;
}
void UpdateProductAmount(int New_Stock_Amount)
{
Stock_Amount = New_Stock_Amount;
}
void UpdateWholesale_price(float New_Wholesale_Price)
{
Wholesale_Price = New_Wholesale_Price;
}
};
The relevant part of function:
void ReadProductFromFile(product* Products)
{
string Name, Supplier, Note, Wholesale_Price, Retail_Price, Stock_Amount;//wholesale price, stock amount,price are in string so that
//it becomes easy to use getline(). Use stoi() later for turning string to int.
ifstream ReadProductFromFile;
ReadProductFromFile.open("product.txt");
if (!ReadProductFromFile)
{
perror("Product File failed to open");
return;
}
while(!EOF)
{
/*read product info txt file------>*/
getline(ReadProductFromFile, Name);
getline(ReadProductFromFile, Wholesale_Price);
getline(ReadProductFromFile, Retail_Price);
getline(ReadProductFromFile, Stock_Amount);
/*update product info---------->*/
Products->Name = Name;
Products->UpdateWholesale_price(stoi(Wholesale_Price));
Products->UpdateProductAmount(stoi(Stock_Amount));
Products->UpdateRetailPrice(stoi(Retail_Price));
}
}
Relevant part of Main function:
int main(int argc, char const *argv[])
{
product Products[10];
ReadProductFromFile(Products+5);//is this the right way to send Products[5]? tried &(product[5]) but error
return 0;
}
Input:
Bananas
210
270
310
i'm learning how to program in c++ and i'm facing into a problem:
I have a struct called Professeur, where Cours and Etudiant are other structs (not the problem here) :
struct Professeur {
std::string Nom;
int Ancien;
Cours* ListeDeCours;
Etudiant* ListeDEtudiant;
Professeur* Suivant;
};
In my program i read a file and then store the data in these structure. However when i want to display the info stored in the "Suivant" Professeur i have a problem, see :
The data file :
Prof1
1
Cours11
Cours12
Cours13
&
Etudiant11
Etudiant12
Etudiant13
$
Prof2
2
Cours21
Cours22
Cours23
&
Etudiant21
Etudiant22
Etudiant23
$
And the output :
2
1
1
6304032
As you can see, newprof->Ancien don't give me the same value and i don't know why as i don' modify it (i suppose). So i did a test program, where i create my struct by myself and it work perfectly:
I searched everything but i don't know why it's not working.. Could someone take a look ? Thanks a lot
Here is code where the problem should be located :
test.cpp
ifstream fichier;
vector<DossierProfesseur::Professeur> ContainerProf;
vector<DossierProfesseur::Cours> ContainerCours;
vector<DossierProfesseur::Etudiant> ContainerEtudiant;
DossierProfesseur::DossierProfesseur(string FP){
fichier.open(FP);
if (fichier.is_open() ){
Professeur premier = DossierProfesseur::CreationListeProfesseur();
tete = &premier;
Professeur *newprof = DossierProfesseur::getNextProf(tete);
cout<< newprof->Ancien<<"\n";
cout<< tete->Ancien<<"\n";
cout<< tete->Ancien<<"\n";
cout<< newprof->Ancien<<"\n";
}
else{
printf("Error while openning file");
}
}
DossierProfesseur::Professeur* DossierProfesseur::getNextProf(DossierProfesseur::Professeur* prof){
return prof->Suivant;
}
DossierProfesseur::Professeur DossierProfesseur::CreationListeProfesseur(){
Professeur prof;
Cours cours;
Etudiant etudiant;
if(!fichier.eof()){ //Fin du fichier
getline(fichier,prof.Nom);
string ancien;
getline(fichier,ancien);
prof.Ancien = stoi(ancien);
Professeur nextProf = DossierProfesseur::CreationListeProfesseur();
prof.Suivant = &nextProf;
}
else{
prof.Nom = string();
prof.Ancien = 0;
prof.ListeDeCours = NULL;
prof.ListeDEtudiant = NULL;
prof.Suivant = NULL;
}
ContainerProf.push_back(prof);
return ContainerProf.back();
}
int main()
{
string dest = "FP.txt";
DossierProfesseur dos (dest);
return 0;
}
test.h :
#ifndef DossierProfesseur_h
#define DossierProfesseur_h
#include <iostream>
#include <fstream>
#include <cstring>
#include <stdlib.h>
class DossierProfesseur
{
public:
DossierProfesseur(std::string FP);
struct Cours{
std::string Sigle;
Cours* Suivant;
};
struct Etudiant{
std::string Sigle;
Etudiant* suivant;
};
struct Professeur {
std::string Nom;
int Ancien;
Cours* ListeDeCours;
Etudiant* ListeDEtudiant;
Professeur* Suivant;
};
Professeur CreationListeProfesseur();
Professeur *getNextProf(Professeur *prof);
Professeur* tete;
private:
};
#endif
Edit :
Using vectors, i have the same output as previously:
2 - 0x7ffe26c10520
1
1
6320480 - 0x7ffe26c10520
They point to the same adress, but have different values
To use vectors i used this :
vector ContainerProf; as a global variable
And then in CreationListeEtudiant :
Insted of returning prof, i return this :
ContainerProf.push_back(prof);
return ContainerProf.back();
Did i do something wrong?
DossierProfesseur::Professeur DossierProfesseur::CreationListeProfesseur(){
Professeur prof;
Cours cours;
...
cours = DossierProfesseur::CreationListeCours();
prof.ListeDeCours = &cours;
etudiant = DossierProfesseur:
...
return prof;
}
You create cours as a local object inside this function, so cours will cease to exist when this function returns. Yet you stash the address of cours inside the prof object you return by value. So you are returning an object to the caller that contains a pointer to an object that no longer exists. Attempting to dereference that pointer is disastrous.
Please don't use pointers this way. It makes managing the lifetimes of objects extremely difficult.
So first I created a struct to contain the following:
template <class T>
struct ListNode
{
unsigned int id;
T data;
ListNode *next_left;
ListNode *next_right;
};
And a class with the following:
template <class T>
class List
{
public:
unsigned int id_count;
ListNode<T> *tail;
List()
{
tail = NULL;
id_count = 0;
}
unsigned int add(T item)
{
id_count += 1;
ListNode<T> *n = new ListNode<T>;
n->id = id_count;
n->data = item;
n->next_left = tail;
n->next_right = NULL;
tail = n;
if (n->next_left != NULL)
n->next_left->next_right = n;
return id_count;
}
ListNode<T> *getNode(unsigned int id)
{
bool found = false;
ListNode<T> *np = tail;
while(np != NULL)
{
if (np->id == id)
{
found = true;
return np;
break;
}
else
{
np = np->next_left;
}
}
return NULL;
}
};
Here is a link to the exact code of main.cpp: http://pastebin.com/fHhsvd9A
So in my main.cpp I create a List instance and a Node pointer:
List<F3D_model> GameEntities;
ListNode<F3D_model> *np;
Then I create two model class instances of the F3D_model Class and add them to the List intsance I created:
F3D_model model;
model.create();
F3D_model model2;
model2.create();
GameEntities.add(model);
GameEntities.add(model2);
Print models' information:
Created with ID: 1
Created with ID: 2
Model 1 Address: 07091F28
Model 2 Address: 070919D0
Model 1 Angle: 0
Model 2 Angle: 0
Tail ID: 2
Tail Data: 0
Tail Address: 070919D0
Code used to print information:
printf("Created with ID: %i\n",GameEntities.add(model));
printf("Created with ID: %i\n",GameEntities.add(model2));
printf("Model 1 Address: %p\n",GameEntities.getNode(1));
printf("Model 2 Address: %p\n",GameEntities.getNode(2));
printf("----------------\n");
printf("Model 1 Data: %i\n",GameEntities.getNode(1)->data.angle);
printf("Model 2 Data: %i\n",GameEntities.getNode(2)->data.angle);
printf("----------------\n");
printf("Tail ID: %i\n",(GameEntities.tail->id));
printf("Tail Data: %i\n",(GameEntities.tail->data.angle));
printf("Tail Address: %p\n",(GameEntities.tail));
printf("----------------\n");
( angle is a public var in F3D_model class )
Everything looks right.
So I have a keypress event where I add a value to the models' angle.
GameEntities.getNode(1)->data.angle += 60;
GameEntities.getNode(2)->data.angle += 60;
and then it prints again the values.
So the problem is that when I press the key it prints the same, as if I hadn't added the values.
BUT when I press the key it does move the model on the screen, so it is actually adding the values. And when I change the type from F3D_model to int and do the same process, it works just fine.
SO my question is why isn't it working when I use the F3D_model, and how can I make it work?
From what you've described, it sounds like the issue is just how you're printing the angle:
printf("Model 1 Data: %i\n",GameEntities.getNode(1)->data.angle);
printf("Model 2 Data: %i\n",GameEntities.getNode(2)->data.angle);
You've used %i which is an integer format specifier. You've said it prints what you expect when you change the definition of angle to be an int. If you change the format string to %f to print a float, or print static_cast<int>( GameEntities.getNode(1)->data.angle ) it should work.
The problem I can think of is that you use model and model2 when printing values, but you should use your nodes instead, because they are copies of the created models.
You can store pointers to models instead of models themselves in your list, to avoid copying models.
I want to check the age of person by passing in a delegate type in a method and iterating through list.
If i find that person is a child....I want to remove him from the list...because i already performed a test on him and don't want to perform test again.
But i am getting exception after i am remove element from the list...Exception is that i cannot modify the collection during foreach loop.Is there is any way by which i can achieve this because i don't want to perform operation on same person again when age of person is already decided in last operation.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DelegateApp
{
/// <summary>
/// A class to define a person
/// </summary>
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
class Program
{
//Our delegate
public delegate bool FilterDelegate(Person p);
static void Main(string[] args)
{
//Create 4 Person objects
Person p1 = new Person() { Name = "John", Age = 41 };
Person p2 = new Person() { Name = "Jane", Age = 69 };
Person p3 = new Person() { Name = "Jake", Age = 12 };
Person p4 = new Person() { Name = "Jessie", Age = 25 };
//Create a list of Person objects and fill it
List<Person> people = new List<Person>() { p1, p2, p3, p4 };
DisplayPeople("Children:", people, IsChild);
DisplayPeople("Adults:", people, IsAdult);
DisplayPeople("Seniors:", people, IsSenior);
Console.Read();
}
/// <summary>
/// A method to filter out the people you need
/// </summary>
/// <param name="people">A list of people</param>
/// <param name="filter">A filter</param>
/// <returns>A filtered list</returns>
static void DisplayPeople(string title, List<Person> people, FilterDelegate filter)
{
Console.WriteLine(title);
foreach (Person p in people)
{
if (filter(p))
{
Console.WriteLine("{0}, {1} years old", p.Name, p.Age);
people.Remove(p);
}
}
Console.Write("\n\n");
}
//==========FILTERS===================
static bool IsChild(Person p)
{
return p.Age <= 18;
}
static bool IsAdult(Person p)
{
return p.Age >= 18;
}
static bool IsSenior(Person p)
{
return p.Age >= 65;
}
}
}
Use a for loop instead of a foreach loop. You can't use foreach loops if you're changing the list as you're looping through it. When using the for loop, you should count backwards through your loop so that you're removing elements from the end.
for (int i = people.Count - 1; i >= 0; i--)
{
Person p = people[i];
if (filter(p))
{
Console.WriteLine("{0}, {1} years old", p.Name, p.Age);
people.RemoveAt(i);
}
}
The reason to go backwards is that otherwise you will skip over some elements. For example, suppose you want to remove elements 4 and 5 of your original list. If you count forwards, then when your loop counter is 4, you'll remove element 4. So then element 5 becomes the new element 4, and element 6 becomes the new element 5. Then on the next iteration of your loop, your counter increments to 5. Now this iteration of the loop is operating on your current element 5 (which was originally your element 6). So your original element 5 got skipped over entirely. Counting backwards avoids this situation. If you were going forward through your list, you'd have to decrement your loop counter each time you removed an element and that's more confusing.
Its my first time asking for help on programming. I have been working on a register program for my programming class for weeks which involves classes. Its rather frustrating for me. I have to use two classes: StoreItem and Register. StoreItem deals with the small list of items that the store sells. The register class deals mostly with processing the items, making a total bill and asking the user to pay with cash.
Here is the StoreItem.cpp file:
//function definition
#include <string>
#include <iostream>
#include "StoreItem.h"
#include "Register.h"
using namespace std;
StoreItem::StoreItem(string , double)
{
//sets the price of the current item
MSRP;
}
void StoreItem::SetDiscount(double)
{
// sets the discount percentage
MSRP * Discount;
}
double StoreItem::GetPrice()
{ // return the price including discounts
return Discount * MSRP;
}
double StoreItem::GetMSRP()
{
//returns the msrp
return MSRP;
}
string StoreItem::GetItemName()
{
//returns item name
return ItemName;
}
StoreItem::~StoreItem()
{
//deletes storeitem when done
}
Here is the Register.cpp:
Note that the last 5 function definitions in this one arent finished yet...
// definition of the register header
#include "Register.h"
#include "StoreItem.h"
using namespace std;
Register::Register()
{ // sets the initial cash in register to 400
CashInRegister = 400;
}
Register::Register(double)
{ //accepts initial specific amount
CashInRegister ;
}
void Register::NewTransAction()
{ //sets up the register for a new customer transaction (1 per checkout)
int NewTransactionCounter = 0;
NewTransactionCounter++;
}
void Register::ScanItem(StoreItem)
{ // adds item to current transaction
StoreItem.GetPrice();
// this probably isnt correct....
}
double Register::RegisterBalance()
{
// returns the current amount in the register
}
double Register::GetTransActionTotal()
{
// returns total of current transaction
}
double Register::AcceptCash(double)
{
// accepts case from customer for transaction. returns change
}
void Register::PrintReciept()
{
// Prints all the items in the transaction and price when finsished
}
Register::~Register()
{
// deletes register
}
My main question is where Register::ScanItem(StoreItem)... is there a way to correctly call a function from the storeItem Class into the Register scanitem function?
You have:
void Register::ScanItem(StoreItem)
{ // adds item to current transaction
StoreItem.GetPrice();
// this probably isnt correct....
}
This means that the ScanItem function takes one argument of type StoreItem. In C++ you can specify just the type and make the compiler happy. But if you intend to use the argument, you must give it a name. For example:
void Register::ScanItem(StoreItem item)
{
std::cout << item.GetItemName() << " costs " << item.GetPrice() << std::endl;
}
To be able to call a member function of the object you're passing as the parameter, you need to name the parameter, not just its type.
I suspect you want something like
void Register::ScanItem(StoreItem item)
{
total += item.GetPrice();
}