Problem z zapisem struktury do pliku

0

Od razu mówię że bawię się z c++ może 10h na razie.
Moim problemem jest to że w linijce [komentarz] wyskakuje błąd. Moim celem było zapisanie całej zawartości struktury do pliku [coś ala zapisywanie tablicy typów w pascalu]. Niestety nie jestem w stanie wymyślić dlaczego mam taki błąd. Ktoś mógłby mi ktoś wytłumaczyć czemu jest taki błąd?:p [tylko bez odsyłania do jakiegoś kursu bo mam otwarty jeden na zakładce i tak czy siak nie umiem dojść do tego]

#include <fstream>
#include <cstdio>
#include <iostream>
#include <string>
#include <stdlib.h>

const int maxitem = 99;
const std::string item_file = "D:\\_CO\\_alfa\\item.dat";

struct spell
{
    std::string spell_name;
    int spell_level;
    int spell_type;
    int spell_atk;
    int spell_heal;
    int spell_buff;
    int spell_class;
    int spell_mc;

};


int spell_()
{
    spell spell_list[maxspell];
    std::fstream plik( mob_file.c_str(), std::ios::in | std::ios::out );
    plik.write( spell_list[0], spell.spell_name ); // error: expected primary-expression before '.' token

}
0

A dokumentację do fstream.write() czytał?

0

z http://www.cplusplus.com/reference/iostream/ostream/write/ ? tak. że tak powiem, nie bardzo odpowiada (przynajmniej mi) gdzie mam błąd:p

0

Dodatkowo spell jest nazwą typu, a spell_name polem obiektów mających ten typ. Żeby odwołać się do pola potrzebujesz jakiś obiekt tej klasy, np. jakiś element tablicy spell_list. Dodatkowo (nawet po poprawieniu fstream::write()) tak łatwo stringa do pliku nie zapiszesz, musisz go w pewien (nawet najprostszy) sposób zserializować.

0

zserializować tzn?:p

0
tariel36 napisał(a)

z http://www.cplusplus.com/reference/iostream/ostream/write/ ? tak. że tak powiem, nie bardzo odpowiada (przynajmniej mi) gdzie mam błąd:p

To przeczytaj jeszcze raz, bo ja tam widzę dwa błędy (co najmniej). Pomogę Ci z jednym: drugi argumentem z pewnością nie może być std::string.
Musisz się nauczyć korzystania z dokumentacji, bo bez tego będzie bardzo ciężko.

0
tariel36 napisał(a)

zserializować tzn?:p
Tzn. utrwalić stan obiektu do strumienia plikowego lub pamięciowego. C++ chyba nie ma wbudowanej serializacji, ale możesz użyć istniejących bibliotek - http://www.boost.org/doc/libs/1_36_0/libs/serialization/doc/index.html

0

Ogólnie chodziło mi o to, żeby nie zapisywać danych klasy std::string, ponieważ tak nie zapisze się napis. Najprościej by było zapisać tablicę znaków zakończonych zerem (albo wszystko zapisywać tekstowo przez <<).

0

zapisywanie tekstowo raczej odpada, bo potem mogą być problemy z rodzajami zmiennych jak się domyślam, tak? Dobra to muszę jeszcze trochę poćwiczyć z czymś prostszym chyba ;o

0

W przypadku write'a i tak nie zapisujesz typu zmiennej. Zapisujesz po prostu jakiś fragment pamięci do pliku. W ramach zrozumienia używania tej funkcji spróbuj zapisać i wczytać jakiegoś inta, żeby się zapoznać z argumentami. Dodatkowo jak jesteś pod windowsem, musisz używać trybu binarnego, bo inaczej będziesz miał głupie błędy (na innych systemach powinieneś, jeżeli korzystasz z takich funkcji, jak fstrem::write(), choć jak twój system używa unixowego znaku nowej linii nie powinno być kłopotów).

0

Uwaga na endianess!

0
Kumashiro napisał(a)

Uwaga na endianess!

90% współczesnych maszyn jest little. O ile plik nie będzie przenoszony na inną, problemu nie ma.

Stringa tak nie zapiszesz.

Ja bym użył stałorozmiarowego char*a, czyli np. char name[20]. Wtedy ładnie się zserializuje.

0
Razi91 napisał(a)

90% współczesnych maszyn jest little. O ile plik nie będzie przenoszony na inną, problemu nie ma.

Nie zamykajmy samochodów. 90% obywateli nie jest złodziejami ;)

Razi91 napisał(a)

Ja bym użył stałorozmiarowego char*a, czyli np. char name[20]. Wtedy ładnie się zserializuje.

char[] już jest zserializowany. To, co zapiszesz w pliku odpowiada dokładnie temu, co leży w pamięci. Jeśli serializujemy, to możemy użyć zmiennego rozmiaru, np. w pierwszych bajtach zapisać długość łańcucha znaków, a za nimi sam łańcuch (bajt zerowy można wywalić, gdyż mamy informację o rozmiarze). W ten sposób nie będziemy zapisywać śmieci do pliku, które czasami są nader ciekawe ;)
Zapisywanie danych do plików jest proste. Jeśli jednak nie chcemy się w to bawić, a niewielki narzut danych nie jest nam straszny, można użyć BER/ASN.1, do których są stosowne biblioteki (zatroszczą się także o endianess).

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