Zapis i odczyt vektora obiektów do pliku

Odpowiedz Nowy wątek
2019-09-02 12:48
0

Witam,

Dana jest klasa:

class wielomian {

    int stopienW;

    float wspolczynnikiW[100]; 

    float poczatekPrzedzialu; 

    float koniecPrzedzialu;

    int iloscIteracji; 

    int q;  

    int p;
}

i vektor:

vector < wielomian > listaWielomianow;

Jak mogę zapisać ten wektor do pliku, tak by pozniej go móc odczytac w programie i wyswietlic zapisane wielomiany wraz z parametrami? Próbowałem biblioteką fsteam ale potrafie zapisywac tylko zmienne string. Z góry dzięki za pomoc.

Co masz zrobione? Czego próbowałeś? - MarekR22 2019-09-02 12:55

Pozostało 580 znaków

2019-09-02 13:36
1

Musisz te dane zserializować a potem zdeserializować podczas wczytywania. Pamiętaj, że floaty często są wypisywane z pewną precyzją przez co dane mogą się trochę różnić.

Pozostało 580 znaków

2019-09-02 13:39
0

Zobacz http://uscilab.github.io/cereal/

no fajnie, tyle, że to jest newbie, który zapewne jest ograniczony do standardowej biblioteki. - MarekR22 2019-09-02 13:45

Pozostało 580 znaków

2019-09-02 15:01
0

Dodaj sobie do tej klasy dwie funkcje

class wielomian {
// ...
  std::string serialize() const;
  bool deserialize ( const std::string & str );
};

Funkcja serialize() powinna zwrócić pełną tekstową reprezentację tego wektora w jednoznacznym formacie, np.: "5; 1;2;3;4;5; 1.1;1.5; 10; 4; 5"
Funkcja "deserialize" powinna odtworzyć ten obiekt na podstawie tego typu string-a.

Przetestuj czy obie funkcje działają poprawnie BEZ zapisu/odczytu do/z pliku.

Jeśli działają dobrze - wynik serialize dla każdego obiektu po kolei zapisz do pliku.

Przy odtwarzaniu - w pętli

  • wczytaj wiersz z pliku
  • jeśli się nie udało - koniec
  • jeśli jest OK - stwórz sobie zmienną lokalną typu wielomian (np. wielomian tmp; )
  • wywołaj dla niej deserialize (*)
  • dodaj ją do wektora

*) Uwzględnij błędy przy deserializacji (czyli co zrobić, jeśli tekst podany do deserialize nie jest poprawnym opisem wielomianu).

Przy wszystkich wadach tekstowej serializacji - ma ona dwie ważne zalety

  • na początku jest intuicyjna i łatwa do zrozumienia
  • plik z danymi da się obrabiac notatnikiem ;)
IMO bardziej naturalne jest: std::ostream& serialize(std::ostream&) i std::istream& deserialize(std::istream&). - MarekR22 2019-09-02 15:57
Zgadzam się, ale nie(koniecznie) dla osoby początkującej ;) - Bartłomiej Golenko 2019-09-02 16:03

Pozostało 580 znaków

2019-09-02 15:29
1

Można to zapisać normalnie do pliku bez jakiś dziwacznych serializacji. Zrzucasz po prostu tą pamięć którą zarezerwowano dla obiektu razy ilość tych obiektów w twoim przypadku w wektorze.
Jeżeli masz pola w klasie o określonej wielkości np tablica float[25], co innego gdybyś chciał np zapisać *float, wtedy jakiegoś jednego bajta musiałbyś użyć do zapisu wielkości tej tablicy. Ale potem odczyt musiałby być też trochę inny.

Ja tak zawsze swoje struktury danych w projektach zapisywałem, masz fajny plik binarny. Możesz sobie zrobić w nim jakieś crc na początku. Jest dużo możliwości.

#include "stdio.h"
#include "stdlib.h"
#include "vector"

class person 
{
    int age;
    float weight;
    float test[2];

public:

    person(int _age, float _weight)
    {
        age = _age;
        weight = _weight;
        test[0] = 0.0;
        test[1] = 1.1;
    }
};

bool file_write(std::vector<person> &p)
{
    FILE * f = fopen("test.file","wb");
    if(f == NULL)
        return false;

    fwrite(&p ,sizeof(person),p.size() ,f);
    fclose(f);

    return true;
}

bool file_read(std::vector<person> &p)
{
    FILE * f = fopen("test.file","rb");
    if(f == NULL)
        return false;

    fseek (f, 0, SEEK_END);
    long size = ftell (f);
    rewind(f);

    fread(&p ,sizeof(person),size ,f);
    fclose(f);

    return true;
}

int main(int argc, char **argv)
{

    std::vector<person> v1Person;
    std::vector<person> v2Person;

    v1Person.push_back(person (10,10.5));
    v1Person.push_back(person (11,11.5));

    if(!file_write(v1Person))
        printf("error write");

    if(!file_read(v2Person))
        printf("error read");

    system("pause");

}
Mocno ryzykowne. Rozmiary typów danych, alignment, kwestia pakowania danych, różnice w LE/BE w zależności od architektury... - Bartłomiej Golenko 2019-09-02 16:03

Pozostało 580 znaków

2019-09-02 15:54
0

Można to zapisać normalnie do pliku bez jakiś dziwacznych serializacji.

Nie

Zrzucasz po prostu tą pamięć

To też forma serializacji.

zarezerwowano dla obiektu razy ilość tych obiektów w twoim przypadku w wektorze

To nie zadziała (w ogólnym przypadku) bez znajomości jak wygląda std::vector w środku, nie masz nigdzie gwarancji, że tam jest jakakolwiek tablica, a zrzucanie surowych wskaźników to bardzo głupi pomysł, który na 100% nie zadziała po wczytaniu.

Pozostało 580 znaków

2019-09-03 14:27
0
hauleth napisał(a):

... to bardzo głupi pomysł, który na 100% nie zadziała po wczytaniu.

Chyba że wczytasz natychmiast po zapisaniu nie czyszcząc pamięci - czyli nawet sprawdzenie że nie zadziała trzeba zrobić z głową

hauleth napisał(a):

.... nie masz nigdzie gwarancji, że tam jest jakakolwiek tablica ...

A to akurat nie zupełnie prawda: http://www.cplusplus.com/reference/vector/vector/data/


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 3x, ostatnio: _13th_Dragon, 2019-09-04 14:34

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0