• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Aplikacja pseudo bazodanowa z wykorzystaniem plików tekstowych

Object Storage Arubacloud
0 głosów
678 wizyt
pytanie zadane 1 września 2016 w C i C++ przez rubiikk Obywatel (1,900 p.)
otagowane ponownie 3 września 2016 przez draghan
Cześć,

Chciałbym skorzystać trochę z Waszej wiedzy i pomocy. Przyznam się szczerze, że jest to pierwszy taki większy program, który chcę wykonać. Całą aplikację chcę napisać języku C++ i musi ona zawierać m.in. obsługę plików, edycję plików, dodawanie/usuwanie rekordów, wyszukiwanie rekordów i jakieś sortowanie wyświetlanych danych. Myślałem sobie, że dane z pliku można wczytać do listy (biblioteka STL). Tylko zasadnicze pytanie? W jakiej kolejności powinienem zbudować taki program?

1. Stworzenie klas, które odpowiednio będą przechowywać dane (jedna klasa zawierająca informacje o pacjentach, druga o lekarzach, trzecia o jakaś historia chorób pacjenta).

2. Menu z funkcją case.
3. Wczytywanie danych z pliku do listy i wyświetlanie ich na ekran.
4. Zapisywanie do pliku.

Ktoś ma jakieś rady, które ułatwią mi napisanie pierwszego programu?

3 odpowiedzi

0 głosów
odpowiedź 1 września 2016 przez rubiikk Obywatel (1,900 p.)
Mam pytanie. Jak dane wczytane z pliku tekstowego przekazać do vectora?
komentarz 13 września 2016 przez draghan VIP (106,230 p.)
Dlaczego? Obecna struktura daje radę. Łańcuch, zwracany przez funkcję, może przecież zawierać przełamania linii.
komentarz 13 września 2016 przez rubiikk Obywatel (1,900 p.)

No dobra, to w takim razie przy strukturze pliku nic nie zmieniam i zostawiam tak, jak jest, czyli:

ID
Imię
Nazwisko
Wiek
Numer Telefonu

W takim razie muszę zmodyfikować moją funkcję WczytywanieDanych o to, co napisałeś?

1
komentarz 13 września 2016 przez draghan VIP (106,230 p.)
Najpierw metoda klasy, o której rozmawiamy. Bo bez niej nie dostaniesz się do danych pacjenta - wszak wszystkie są prywatne (i tak powinno zostać).

A potem modyfikacja zarówno wczytywania danych (tutaj możesz mieć problem z dodaniem obiektu Patient do wektora, ale myślę że sobie poradzisz) jak i zapisywania danych (gdzieś wyżej już jakiś wstępny szkic Ci przedstawiłem).
komentarz 14 września 2016 przez rubiikk Obywatel (1,900 p.)

Tak szczerze mówiąc, to nie za bardzo wiem jak to zrobić. W mainie mam 5 intów do których zapisywane są dane po wczytaniu i wyświetleniu danych. Może powinienem najpierw wczytać dane do programu, inną opcją w menu je wyświetlać/zapisywać? W tym momencie stworzyłem sobie funkcję getInfo w klasie, ale kompletnie nie wiem, co mam zrobić dalej. Zapisać tutaj w wektorze Patients wszystkie dane o pacjentach z pliku?

void Patient::getInfo()
{
    cout << "Podaj numer ID pacjenta: ";
    cin >> id;
}

 

1
komentarz 17 września 2016 przez draghan VIP (106,230 p.)

Pokażę Ci, jak należy zmodyfikować Twój aktualny program, aby korzystał z Twojej klasy Patient.

Na początek dodałem dwie metody do klasy:

    std::string get_data_string() const;
    void say_hello() const;

Pierwsza służy do tego, aby zebrać wszystkie dane z obiektu i wypluć stringa, którego możesz wrzucić do pliku i tym samym zapisać dane tego pacjenta.
Druga przedstawia pacjenta, drukując informacje o nim na ekranie.
Modyfikatory const za listą parametrów funkcji obiecują kompilatorowi, że nie będą modyfikowały obiektu, a jedynie jakoś nieinwazyjnie przetworzą jego dane.

Definicje tych funkcji są bardzo proste. Nowością dla Ciebie może być stringstream, ale myślę że łatwo go ogarniesz - krótkie wyjaśnienie masz w komentarzu.

Usunąłem destruktor, który tylko zaciemniał wydruki programu.

No i w oczy powinny Ci się rzucić zmiany w pliku main.cpp.

// patient.h
#pragma once
#include <string>

class Patient
{
public:
    Patient(int id, std::string name = "Imie", std::string surname = "Nazwisko", unsigned int age = 0, unsigned int phone_numer = 0);

    std::string get_data_string() const;
    void say_hello() const;

private:
    int id;
    std::string name;
    std::string surname;
    unsigned int age;
    unsigned int phone_number;
};

// patient.cpp
#include <iostream>
#include <string>
#include <sstream> // +
#include <cstdlib> // !
#include "patient.h"

using std::string;
using std::cin;
using std::cout;

Patient::Patient(int id, string name, string surname, unsigned int age, unsigned int phone_number):
    id{id}, name{name}, surname{surname}, age{age}, phone_number{phone_number}
{
}

string Patient::get_data_string() const
{
    std::stringstream data; // obiekt strumienia łańcucha - coś jak cout dla std::string
    data << id << '\n';
    data << name << '\n';
    data << surname << '\n';
    data << age << '\n';
    data << phone_number << '\n';

    return data.str(); // metoda std::stringstream::str() zwraca ze strumienia obiekt std::string
}

void Patient::say_hello() const
{
    cout << "ID: [" << id << "] " << name << " " << surname << " " << age << " lat || " << "Numer telefonu: " << phone_number << "\n";
}
// main.cpp
#include <string>
#include <vector>
#include <fstream>
#include <cstdlib>
#include <iostream>
#include "patient.h"

void WczytywanieDanych()
{
    std::vector<Patient> patients;
    int id;
    std::string name, surname;
    unsigned char age;
    unsigned int phone_number;

    std::ifstream file("patient.txt");
    if(file.good())
    {
        std::string line; //przechowuje pobrana linie tekstu:
        int number_line = 0;
        while(getline(file, line))
        {
            switch(number_line % 5)
            {
            case 0:
                id = atoi(line.c_str());
                break;
            case 1:
                name = line;
                break;
            case 2:
                surname = line;
                break;
            case 3:
                age = atoi(line.c_str());
                break;
            case 4:
                phone_number = atoi(line.c_str());

                patients.push_back(Patient{id, name, surname, age, phone_number});
                break;
            }
            number_line++;
        }

        for(size_t i = 0; i < patients.size(); ++i)
        {
            patients[i].say_hello();
        }
    }
    else
    {
        std::cout << "Ten plik nie istnieje - blad.";
    }
}

void SaveToFile()
{
    int id;
    std::string name, surname;
    unsigned int ages = 0;
    unsigned int phone_number;
    std::cout << "Podaj identyfikator: ";
    std::cin >> id;
    std::cout << "Podaj imie: ";
    std::cin >> name;
    std::cout << "Podaj nazwisko: ";
    std::cin >> surname;
    do
    {
        std::cout << "Podaj wiek: ";
        std::cin >> ages;
        if (ages > 125)
        {
            system("CLS");
            std::cout << "Za duzy wiek. Podaj poprawna wartosc! \n \n";
        }
    }
    while (ages > 125);
    std::cout << "Podaj numer telefonu: ";
    std::cin >> phone_number;
    std::ofstream file("patient.txt", std::ios::app);

    if(file.good())
    {
        Patient patient{id, name, surname, ages, phone_number};
        file << patient.get_data_string();
        file.close();
    }
    else
    {
        std::cout << "Ten plik nie istnieje - blad.";
    }
}

void Menu()
{
    int zmienna;
    std::cout << "1. Wyswietl dane o pacjentach. \n";
    std::cout << "2. Wprowadz nowego pacjenta. \n \n";
    std::cout << "Twoj wybor: ";
    std::cin >> zmienna;
    system("CLS");
    switch(zmienna)
    {
    case 1:
    {
        WczytywanieDanych();
        std::cout << "\nAby wrocic do menu kliknij przycisk: [1]. ";
        int choise;
        std::cin >> choise;
        if (choise = 1)
        {
            system("CLS");
            Menu();
        }
    }
    break;
    case 2:
    {
        SaveToFile();
        std::cout << "\nAby wrocic do menu kliknij przycisk: [1]. ";
        int choise;
        std::cin >> choise;
        if (choise = 1)
        {
            system("CLS");
            Menu();
        }
    }
    break;
    default:
        std::cout << "Zly wybor - wybierz ponownie.";
    }
}

int main()
{
    Menu();
}

Obsługa tego programu jest mało intuicyjna. Nie ma żadnej opcji "wyjdź", co by się jednak przydało. ;)

No i pytanie: jesteś pewny, że chciałeś w warunku przypisywać wartość do zmiennej choise (po angielsku "wybór" to jest "choice" ;)?

if (choise = 1)

W ten sposób zawsze przypisujesz tej zmiennej wartość 1, co w efekcie zawsze spowoduje że warunek będzie prawdziwy. ;)

Jeśli masz jakieś pytania, to pytaj śmiało.

0 głosów
odpowiedź 1 września 2016 przez manjaro Nałogowiec (37,390 p.)
Zastanów się nad rozwiązaniem lepszym i nowocześniejszym. Zamiast plików tekstowych baza danych sqlite. Nie ma czego się bać operacje na bazie danych są podobne jak na plikach. Otwierasz bazę operujesz na danych i zamykasz bazę. Prawie to samo a jesteś 20 lat do przodu ;)
komentarz 1 września 2016 przez draghan VIP (106,230 p.)
Ręczne zakodowanie parsowania plików jest rozwijające. Owszem - jak najbardziej baza danych jest rozwiązaniem lepszym technologicznie niż pliki plain-text - ale i te pliki są potrzebne.
komentarz 1 września 2016 przez rubiikk Obywatel (1,900 p.)
Na pewno zaraz po plikach tekstowych wezmę się za bazy danych - wszystko po kolei. Na razie męczę się z jednym problemem, czyli z przestarzałą technologią i plikami :D
komentarz 17 września 2016 przez efiku Szeryf (75,160 p.)
edycja 17 września 2016 przez efiku
No ale co mu szkodzi zrobić interfejs do operacji na bazie? :d

Apka -> interfejs bazy -> implementacja operacji na bazie txt|sqlite|mysql

Ale to taki wyższy lvl :P
0 głosów
odpowiedź 13 września 2016 przez rubiikk Obywatel (1,900 p.)
edycja 13 września 2016 przez rubiikk

Cześć, witajcie ponownie. Odświeżam trochę ten temat i proszę wszystkich o jakieś rady. Poprawiłem trochę błędów, obecnie wyświetlają mi się dane z pliki i zapisują do wektora. Mam również klasę i jak rozumiem w tym momencie moje dane z pliku zapisywane są tylko i wyłącznie w wektorze i nie korzystają w ogóle z klasy, mam rację? Co do zapisywania danych do pliku, to będę musiał popracować w jakiś sposób nad automatycznym tworzeniem unikalnego klucza pacjentów, czyli ID. Może powinienem zrobić menu w inny sposób? Najpierw czytuję zawartość plików do wektora za pomocą jednego z wyborów w głównym menu, a dopiero potem mogę działać z tymi danymi, czyli:
1 - wyświetlanie
2 - zapisywanie danych do pliku
3 - wyszukiwanie danych w pliku
4 - sortowanie danych
5 - usuwanie

Aktualnie tak prezentuje się mój kod. Proszę o wszelkie rady i nakierowania, czy mój tok myślenia jest dobry.

Plik patient.cpp:

#include <iostream>
#include <string>
#include <stdlib.h>
#include "patient.h"

using std::string;
using std::cin;
using std::cout;

Patient::Patient(int id, string name, string surname, unsigned char age, unsigned int phone_number):
    id{id}, name{name}, surname{surname}, age{age}, phone_number{phone_number}
{
}

Patient::~Patient()
{
    cout << "\nDestruktor ";
}

Plik patient.h:

#pragma once
#include <string>

class Patient
{
public:
    Patient(int id, std::string name = "Imie", std::string surname = "Nazwisko", unsigned char age = 0, unsigned int phone_numer = 0);
    ~Patient();

    //void saveToFile();

private:
    int id;
    std::string name;
    std::string surname;
    unsigned char age;
    unsigned int phone_number;
};

 

komentarz 13 września 2016 przez rubiikk Obywatel (1,900 p.)
edycja 13 września 2016 przez rubiikk

Plik main (po drobnych zmianach):

#include <string>
#include <vector>
#include <fstream>
#include <cstdlib>
#include <iostream>

void WczytywanieDanych()
{
    std::vector<int> ids;
    std::vector<std::string> names;
    std::vector<std::string> surnames;
    std::vector<unsigned int> ages;
    std::vector<unsigned int> phone_numbers;

    int id;
    std::fstream file;
    std::string name, surname;
    unsigned char age;
    unsigned int phone_number;

    file.open("patient.txt", std::ios::in);
    if(file.good() == false)
    {
        std::cout << "Ten plik nie istnieje - blad.";
        //return NULL;
    }

    std::string line; //przechowuje pobrana linie tekstu:
    int number_line = 0;
    while(getline(file, line))
    {
        switch(number_line % 5)
        {
            case 0:
                id = atoi(line.c_str());
                break;
            case 1:
                name = line;
                break;
            case 2:
                surname = line;
                break;
            case 3:
                age = atoi(line.c_str());
                break;
            case 4:
                phone_number = atoi(line.c_str());

                ids.push_back(id);
                names.push_back(name);
                surnames.push_back(surname);
                ages.push_back(age);
                phone_numbers.push_back(phone_number);
                break;
            }
                number_line++;
        }

    for(size_t i = 0; i < names.size(); ++i)
    {
        std::cout << "ID: [" << ids[i] << "] " << names[i] << " " << surnames[i] << " " << ages[i] << " lat || " << "Numer telefonu: " << phone_numbers[i] << "\n";
    }

}

void SaveToFile()
{
    int id;
    std::string name, surname;
    unsigned int ages = 0;
    unsigned int phone_number;

    std::cout << "Podaj identyfikator: ";
    std::cin >> id;
    std::cout << "Podaj imie: ";
    std::cin >> name;
    std::cout << "Podaj nazwisko: ";
    std::cin >> surname;

    do
    {
        std::cout << "Podaj wiek: ";
        std::cin >> ages;

        if (ages > 125)
        {
            system("CLS");
            std::cout << "Za duzy wiek. Podaj poprawna wartosc! \n \n";
        }
    } while (ages > 125);

    std::cout << "Podaj numer telefonu: ";
    std::cin >> phone_number;

    std::fstream file;
    file.open("patient.txt", std::ios::app | std::ios::out);
    if(file.good() == false)
    {
        std::cout << "Ten plik nie istnieje - blad.";
        //return 0;
    }

    file << id << "\n";
    file << name << "\n";
    file << surname << "\n";
    file << ages << "\n";
    file << phone_number << "\n";

    file.close();
}

void Menu()
{
    int zmienna;
    std::cout << "1. Wyswietl dane o pacjentach. \n";
    std::cout << "2. Wprowadz nowego pacjenta. \n \n";
    std::cout << "Twoj wybor: ";
    std::cin >> zmienna;
    system("CLS");

    switch(zmienna)
    {
        case 1:
            {
                WczytywanieDanych();
                std::cout << "\nAby wrocic do menu kliknij przycisk: [1]. ";
                int choise;
                std::cin >> choise;

                if (choise = 1)
                {
                    system("CLS");
                    Menu();
                }
            }
            break;

        case 2:
            {
                SaveToFile();
                std::cout << "\nAby wrocic do menu kliknij przycisk: [1]. ";
                int choise;
                std::cin >> choise;

                if (choise = 1)
                {
                    system("CLS");
                    Menu();
                }
            }
            break;
        default:
            std::cout << "Zly wybor - wybierz ponownie.";
    }
}

int main()
{
    Menu();
}

 

Podobne pytania

0 głosów
1 odpowiedź 132 wizyt
pytanie zadane 12 czerwca 2016 w C i C++ przez rubiikk Obywatel (1,900 p.)
–1 głos
1 odpowiedź 139 wizyt
pytanie zadane 30 kwietnia 2017 w C i C++ przez Aragedens Obywatel (1,120 p.)
0 głosów
1 odpowiedź 268 wizyt
pytanie zadane 8 stycznia 2021 w C i C++ przez bartx3 Początkujący (270 p.)

92,555 zapytań

141,403 odpowiedzi

319,557 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...