// AnE.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<conio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
// The maximum number of patients in queue
#define MAXPATIENTS 30
// define structure for patient information
struct patient
{
char FirstName[50];
char LastName[50];
char ID[20];
};
// define class for queue
class queue
{
public:
queue (void);
int RegisterPatien (patient p);
int RegisterPatientAtBeginning (patient p);
patient GetNextPatient (void);
int CancelAll (patient * p);
void OutputList (void);
char DepartmentName[50];
private:
int ShowAllPatient;
patient List[MAXPATIENTS];
};
// declare member functions for queue
queue::queue ()
{
// Constructor
ShowAllPatient = 0;
}
int queue::RegisterPatien (patient p)
{
// To add a patient (normally) to the queue (to the end).
// returns 1 if successful, 0 if queue is full.
if (ShowAllPatient >= MAXPATIENTS)
{
// queue is full
return 0;
}
// put in new patient
else
List[ShowAllPatient] = p; ShowAllPatient++;
return 1;
}
int queue::RegisterPatientAtBeginning (patient p)
{
// adds a critically ill patient to the beginning of the queue.
// returns 1 if successful, 0 if queue is full.
int i;
if (ShowAllPatient >= MAXPATIENTS)
{
// queue is full
return 0;
}
// move all patients one position back in queue
for (i = ShowAllPatient-1; i >= 0; i--)
{
List[i+1] = List[i];
}
// put in new patient
List[0] = p; ShowAllPatient++;
return 1;
}
patient queue::GetNextPatient (void)
{
// gets the patient that is first in the queue.
// returns patient with no ID if queue is empty
int i; patient p;
if (ShowAllPatient == 0) {
// queue is empty
strcpy(p.ID,"");
return p;}
// get first patient
p = List[0];
// move all remaining patients one position forward in queue
ShowAllPatient--;
for (i=0; i<ShowAllPatient; i++)
{
List[i] = List[i+1];
}
// return patient
return p;
}
int queue::CancelAll (patient * p)
{
// removes a patient from queue.
// returns 1 if successful, 0 if patient not found
int i, j, found = 0;
// search for patient
for (i=0; i<ShowAllPatient; i++)
{
if (stricmp(List[i].ID, p->ID) == 0)
{
// patient found in queue
*p = List[i]; found = 1;
// move all following patients one position forward in queue
ShowAllPatient--;
for (j=i; j<ShowAllPatient; j++)
{
List[j] = List[j+1];
}
}
}
return found;
}
void queue::OutputList (void)
{
// lists entire queue on screen
int i;
if (ShowAllPatient == 0)
{
cout<< "Queue is empty";
}
else
{
for (i=0; i<ShowAllPatient; i++)
{
cout << "First Name : " << List[i].FirstName<<endl;
cout << "Last Name : " << List[i].LastName<<endl;
}
}
}
// declare functions used by main:
patient InputPatient (void)
{
// this function asks user for patient data.
patient p;
cout<<endl<<endl;
cout << "Please enter the information of the Patient"<<endl<<endl;
cout << "First name: "<<endl<<endl;
cin.getline(p.FirstName, sizeof(p.FirstName));
cout << "Last name: "<<endl<<endl;
cin.getline(p.LastName, sizeof(p.LastName));
// check if data valid
if (p.FirstName[0]==0 || p.LastName[0]==0 || p.ID[0]==0)
{
// rejected
strcpy(p.ID,"");
cout << "Error: Data not valid. Operation cancelled.";
getch();
}
return p;
}
void OutputPatient (patient * p)
{
// this function outputs patient data to the screen
if (p == NULL || p->ID[0]==0)
{
cout << "No patient";
return;
}
else
cout << "Patient Information:"<<endl<<endl;
cout << "First name: " << p->FirstName<<endl<<endl;
cout << "Last name: " << p->LastName<<endl<<endl;
}
int ReadNumber()
{
// this function reads an integer number from the keyboard.
// it is used because input with cin >> doesn't work properly!
char buffer[20];
cin.getline(buffer, sizeof(buffer));
return atoi(buffer);
}
void DepartmentMenu (queue * q)
{
// this function defines the user interface with menu for one department
int choice = 0, success; patient p;
while (choice != 6)
{
// print menu
system("CLS");
cout << "<< || Welcome || >> "<<endl << q->DepartmentName<<endl;
cout << "Please enter your choice:"<<endl<<endl;
cout << "1: Register patient"<<endl;
cout << "2: Serve patient "<<endl;
cout << "3: Cancel all patients from queue"<<endl;
cout << "4: Show all patient"<<endl;
cout << "5: Exit"<<endl<<endl<<endl<<endl<<endl<<endl<<endl<<endl;
choice = ReadNumber();
switch (choice)
{
case 1: // Add new patient
p = InputPatient();
if (p.ID[0])
{
success = q->RegisterPatien(p);
system("CLS");
if (success)
{
cout << "Patient added:"<<endl<<endl;
}
else
{
// error
cout << "Sorry: The queue is full. We Cannot add any patient:";
}
OutputPatient(&p);
cout << "Press any key";
getch();
}
break;
case 2: // Call patient for operation /First Come First Surve
p = q->GetNextPatient();
system("CLS");
if (p.ID[0])
{
cout << "Patient to operate:";
OutputPatient(&p);
}
else
{
cout << "Currently there is no patient to operate.";
}
cout << "Press any key to contiune";
getch();
break;
case 3: // Cancel all from queue
p = InputPatient();
if (p.ID[0])
{
success = q->CancelAll(&p);
system("CLS");
if (success)
{
cout << "Patient removed:";
}
else
{
// error
cout << "Sort: We cannot find patient:";
}
OutputPatient(&p);
cout << "Press any key to contiune";
getch();
}
break;
case 4: // Show all patient -> queues
system("CLS");
q->OutputList();
cout << "Press any key";
getch(); break;
}
}
}
// the main function defining queues and main menu
void main ()
{
int i, MenuChoice = 0;
// define queue
queue department[1];
// set department name
strcpy_s (department[0].DepartmentName, "To Emergency Department");
while (MenuChoice != 2)
{
system("CLS");
// Cout menu
cout<<"\n------------------------------------\n";
cout << "Welcome to Waiting Room Management System"<<endl;
cout<<"---------------------------------------\n";
cout << "Please Select a Number from the following menu:"<<endl<<endl;
for (i = 0; i < 1; i++)
{
// write menu item for department i
cout<< "" << (i+1) << ": "<< department[i].DepartmentName;
cout<<endl;
}
cout << "2: Exit"<<endl;
// get user choice
MenuChoice = ReadNumber();
// is it a department name?
if (MenuChoice >= 1 && MenuChoice <= 1)
{
// call submenu for department
// (using pointer arithmetics here:)
DepartmentMenu (department + (MenuChoice-1));
}
}
}
好的,这是等候室的Vc ++。你可以看到代码运行良好,但我有生成ID的问题!我需要为每个患者生成ID(由系统自动生成)。我如何为队列生成ID? 非常感谢!
答案 0 :(得分:3)
通常情况下,您可以通过在该班级中添加static
变量来实现,并且每次获得新患者时,都会将其当前值分配给当前患者,然后递增。
class patient {
// ...
int id;
static int current_id; // added
patient() : id(current_id++) {} // added
};
int patient::current_id; // added
答案 1 :(得分:0)
如果您需要唯一ID,则可以生成GUID。对于VC ++,您可以使用:
extern C
{
#include <Rpc.h>
}
//...
UUID id;
UuidCreate ( &id );
答案 2 :(得分:0)
您可以在创建患者时使用静态变量(如果您希望在那里),在构造函数中增加自身,或者在您添加患者时增加队列中的变量(如果您只想分配在队列中的ID。)
但在你的情况下,我认为你想要第一个解决方案(构造函数中的静态变量)。
答案 3 :(得分:0)
我对SQL数据库有同样的需求,最终得到了这个......
警告:主要是使用混合C和C ++进行错误编程的一个例子(仍然需要转换旧代码),但它的目的是传达这个想法。我相信存在更好的解决方案......
根据当前日期和时间生成(不幸的)基于大字符的ID。这意味着每个下一个自动生成的ID都需要更大:如果它等于或小于,则附加毫秒计时器,代码将等待,直到ID变为唯一。它也可以在没有毫秒的情况下工作,但如果你需要同时生成许多ID(每次暂停一秒钟),这将导致长时间的延迟。如果需要,它还会添加一个可选的后缀(可以帮助省略毫秒)。
我对简单计数器的经验是,在某些情况下它们可能会重复,这让我寻找替代方案。
小心:另一台计算机上的另一个用户可能会生成相同的ID ...(相同的秒或毫秒)
TUID::TUID()
{
*LastID = 0; // char [80] - Global within object
}
void TUID::GetToday (int *d, int *m, int *y)
{
time_t now;
struct tm *ltm;
time (&now);
ltm = localtime (&now);
*y = ltm->tm_year + 1900;
*m = ltm->tm_mon + 1;
*d = ltm->tm_mday;
}
void GetTime (int *h, int *m, int *s)
{
time_t t = time(0); // get time now
struct tm * now = localtime( & t );
*h = now->tm_hour;
*m = now->tm_min;
*s = now->tm_sec;
}
const char *TUID::NewUID (bool bPreviousAttemptFailed, const char *_postfix)
{
int d, m, y,
_h, _m, _s;
bool bSameAsLastUID;
char _uid [80];
GetToday (&d, &m, &y);
do
{
GetTime (&_h, &_m, &_s);
sprintf (_uid, "%04d%02d%02d_%02d%02d%02d%s", y, m, d, _h, _m, _s, _postfix);
bSameAsLastUID = (strcmp (_uid, LastUID) <= 0);
if (bPreviousAttemptFailed || bSameAsLastUID)
sprintf (_uid + strlen (_uid), "_%d",
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count());
}
while (strcmp (_uid, LastUID) <= 0);
strcpy (LastUID, _uid);
return LastUID;
}
这导致ID如下:
20170816_115904 (no post-fix)
20170816_115904i (with post-fix keeping id unique, preventing milliseconds)
20170816_115904i_6427264 (auto-added milliseconds to keep ID unique)
20170816_115904i_6427265
20170816_115904i_6427266
答案 4 :(得分:0)
其他答案都很棒,但正如另一位用户指出的那样,目前接受的答案实际上并不是线程安全的。
要制作线程安全的ID生成函数,我们可以使用原子!这是对当前接受的答案的修改,使其线程安全。
#include <atomic> //std::atomic_uint32_t
class patient
{
// ...
uint32_t id;
static std::atomic_uint32_t current_id; // added
patient() : id(current_id++) {} // added
};
uint32_t patient::current_id; // added
std::atomic_uint32_t
是一个 32 位无符号整数,如果由两个不同的线程同时写入(因为它是原子的)不会有任何数据竞争。
我还将整数更改为无符号。这是因为 ID 永远不会是负数,所以让它无符号是有意义的。