-1

Making a project I have to write patient database and I have a problem. Looking through guids in iтternet I dont understand how to read from file to class and how to write class into file(I realized it using common input, it is better to rewrite it). And I dont understand how to make base constructor for char, like with int

point()
{
x=y=z=0;
}

need like

Patient()
{
name="Mike";
surename="Smith";
adress="New York";
ilness="Cold"
card_number=1;
}

#include <iostream>
#include <string>
#include <fstream>
using namespace std;

int add();
int read();

string path = "base.txt";

class Patient
{
private:
    char *name;
    char *surename;
    char *adress;
    char *ilness;
    int *card_number;
public:
    void set()
    {
        cout << "Enter name:";
        cin >> name;
        cout << "Enter surename:";
        cin >> surename;
        cout << "Enter adress:";
        cin >> adress;
        cout << "Enter diagnosis:";
        cin >> ilness;
        cout << "Enter card number:";
        cin >> *card_number;
    }
    void show()
    {
        cout << "Name:" << name << endl;
        cout << "Surename:" << surename << endl;
        cout << "Adress:" << adress << endl;
        cout << "Cardnumber:" << card_number << endl;
        cout << "Diagnosis:" << ilness << endl;
    }
    void print()
    {
        cout << name << surename << adress << ilness << card_number << endl;
    }
    Patient()
    {
    
    }
    Patient(const char* s) 
    {
        int length = 0;
        while (s[length++] != ' ')
            ;
        name = new char[length];     
        for (int i = 0; i < length; i++)
            name[i] = s[i];
        length = 0;
        
        while (s[length++] != ' ')
            ;
        surename = new char[length];    
        for (int i = 0; i < length; i++)
            surename[i] = s[i];
        length = 0;

        while (s[length++] != ' ')
            ;
        adress = new char[length];     
        for (int i = 0; i < length; i++)
            adress[i] = s[i];
        length = 0;

        while (s[length++] != ' ')
            ;
        ilness = new char[length];       
        for (int i = 0; i < length; i++)
            ilness[i] = s[i];
        length = 0;

        while (s[length++] != '\n')
            ;
        card_number = new int[length];       
        for (int i = 0; i < length; i++)
            card_number[i] = s[i];
    }   
};

int main()
{
    char a;
    
    cout << "Choose the action:" << endl;
    cout << "a. Add new patient" << endl;
    cout << "b. Delete patient" << endl;
    cout << "c. Find for card number" << endl;
    cout << "d. Find for ilnesses" << endl;
    cin >> a;
    switch (a)
    {
    case 'a':
        add();
        break;
    case 'b':
        read();
        break;
    default:
        cout << "error" << endl;

    }
    system("pause");
    return 0;
}

int add()
{
    fstream file;
    file.open(path, fstream::out | fstream::in | ofstream::app);
    if (!file.is_open())
    {
        cout << "Error" << endl;
    }
    else
    {
        string str;
        cout << "Opend" << endl;
        cout << "Enter name" << endl;
        cin >> str;
        file << str<<" ";
        cout << "Enter surename" << endl;
        cin >> str;
        file << str << " ";
        cout << "Enter adress" << endl;
        cin >> str;
        file << str << " ";
        cout << "Enter ilness" << endl;
        cin >> str;
        file << str << " ";
        cout << "Enter card number" << endl;
        cin >> str;
        file << str<<"\n";
                cout << "Sucsesfully added\n";
    }
    
    file.close();
    return 0;
}

int read()
{
    fstream file;
    file.open(path, fstream::out | fstream::in | ofstream::app);
    if (!file.is_open())
    {
        cout << "Error" << endl;
    }
    else
    {
        cout << "Opend" << endl;
        string str;
        Patient first;
        while (file.read((char*)&first,sizeof(Patient)))
        {
            first.print();          
        }       
    }
    file.close();
    return 0;
}

Database example

Mike Smith New_York Cold 1
Charles Williams London Flu 2
Henry Roberts York Coronovirus 3
Robert Garcia Sydney Cold 4

methods how to write from file to class and from class to file

Nfoth
  • 1
  • 1
    Use a serialisation structure, like JSON. Creating an overloaded constructor is just as simple as overloading a method. Also, you want to use `std::string` instead of `const char`. – SimonC Nov 24 '22 at 09:45
  • Since you are already using `std::string` there is absolutely no reason for this `private: char *name; ...`. Change them all to this `private: string name; ...`. Doesn't answer your question, but will make it a whole lot easier. – john Nov 24 '22 at 09:50
  • `I don;t understand how to make a base constructor like with int.` The answer to that is to change `char*` to `string` as suggested in the previous comment. Forget everything you know about `char*`, using `std::string` is the best and easiest way to do strings in C++. – john Nov 24 '22 at 09:53
  • There are plenty of problems with your current code, you seem to lack the knowledge about the most basic facilities of C++ like `std::string`, and you don't seem to know enough about C-style null-terminated strings either. If you can then please invest in [some good C++ books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282). – Some programmer dude Nov 24 '22 at 09:53

1 Answers1

1

If you want to serialise your data structures, it's best to use a library and data format, such as JSON.

Personally, I recommend nlohmann::json because of it's ease of use and flexibility.


Overloading the constructor and serialising data

Overloading your constructor is nothing other than overloading another method in C++.

If your class is Patient:

#include <string>

#include <nlohmann/json.hpp>

using nlohmann::json;
using std::string; // Don't use using namespace std;!

class Patient {
    public:
    Patient() = default;
    explicit Patient(const string& name, const string& surname,
                const string& addr, const string& illness):
        m_name(name), m_surname(surname), m_address(addr), m_illness(illness) {}
    explicit Patient(const json& data) { fromJson(data); }
    virtual ~Patient() = default;
        

    json toJson() const {
        return {
            { "Name", m_name },
            { "Surname", m_surname },
            { "Address", m_address },
            { "Illness", m_illness }
        };
    }

    void fromJson(const json& data) {
        if (data.contains("Name") && data["Name"].is_string()) {
            m_name = data["Name"].get<string>();
        } // and so on
    }

    void dumpJson(const string& filePath) const {
        ofstream out(path, std::ios::out);
        // error checking
        out << filePath; 
    }

    private: // members
        string m_name;
        string m_surname;
        string m_address;
        string m_illness;

};

I haven't tested this code and won't guarantee it will work first try, but it should point you in the right direction. This code requires at least C++11.

SimonC
  • 1,547
  • 1
  • 19
  • 43
  • Minor point : From an OO design point of view, I wouldn't make the serialization functions part of the class. They are not a core responsibility for something representing a Patient. Just have free functions calling the constructor with 4 arguments (or add them to a patient factory class). This way you keep your patient class independent from the actual serialization mechism (and json header files). – Pepijn Kramer Nov 24 '22 at 10:02
  • I agree with you when it comes to deserialisation of the object. The serialisation to JSON however does belong in the object imo – SimonC Nov 24 '22 at 10:06
  • In larger projects I am pretty strict about keeping serialization out of the objects completely. Today day it is a json file and then a few years later its a cloud based key value store (and then having JSON code in your objects doesn't make sense anymore). This comes from having seen products being developed/maintained over decades. – Pepijn Kramer Nov 24 '22 at 10:14
  • Risking going off-topic, I rarely use JSON for (actual) data exchange with a server. JSON is used more for LAN communication, as I mostly work with devices connected via a cellular network, so Protobuf is generally preferred there. I definitely see where you're coming from though. – SimonC Nov 24 '22 at 10:17
  • Yes protobuf here also, but even then I keep my C++ code (+unit tests) completely separated from proto generated types (and add a translation layer in between). Since RPC technologies come and go too :) – Pepijn Kramer Nov 24 '22 at 10:22