Auto generate ID in C++

情到浓时终转凉″ 提交于 2019-12-25 08:00:00

问题


// 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));
            }
    }
}

Okay, it's Vc++ for waiting room. You can see the code is working well, but I have problem with generating ID! I need to generate ID for each patient (auto-generate by system). How I can generate ID for my queue? Thanks alot !


回答1:


Usually, you'd do it by putting a static variable in that class, and each time you get a new patient, you assign its current value to the current patient, then increment it.

class patient { 
    // ...
    int id;

    static int current_id; // added

    patient() : id(current_id++) {} // added
};

int patient::current_id; // added



回答2:


If you want unique ids, you can generate a GUIDs. For VC++, you can use:

extern C
{
   #include <Rpc.h>
}

//...
UUID id;
UuidCreate ( &id );



回答3:


You can use a static variable when you create a patient (if you want it there) that increment itself in the constructor, or a variable in you're queue that increment when you add a patient (if you want to only assign an ID when in the queue).

But in your case, I think you want the first solution (static variable in the constructor).




回答4:


I had the same need for an SQL-database and ended up with this...

Warning: Mostly an example of bad programming with mixing C and C++ (still need to convert old code), but it was meant to convey the idea. I am sure better solutions exist...

It generates (unfortunately) large character based ID's, based on current date and time. This means that every next auto-generated ID needs to be bigger: if it is equal or smaller, a millisecond timer is appended and the code will wait until the ID has become unique. It works without the milliseconds as well, but this will lead to long delays if you need to generate many ID's at once (a second for each pause). If desired, it will also add an optional postfix (can help omit the milliseconds).

My experience with simple counters is, that they might duplicate under certain circumstances, which had me look for an alternative.

Careful: Another user on another computer might generate equal ID's... (same second or millisecond)

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;
}

This results in ID's like this:

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


来源:https://stackoverflow.com/questions/10124609/auto-generate-id-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!