2013-08-12 24 views
5
airport air(1,2,3); //an airport constructor 
ofstream myfile; 
myfile.open("rishab",ios::app||ios::binary); 
myfile.write((char*)air,sizeof(airport); 
myfile.close(); 

Takie polecenia są w moim programie wywoływane wiele razy, aby uzyskać informacje o wielu lotniskach. Zasadniczo plik binarny jest pełen lotnisk. Muszę odczytywać wszystkie te lotniska w tablicy później. Jak mogę odczytać plik, aby uzyskać zestaw lotnisk.C++ Odczyt i zapis wielu obiektów tej samej klasy

Przeprosiny, jeśli to pytanie jest zbyt proste. Uczę się w szkole średniej o wskaźnikach i najkrótszych wykresach ścieżki.

+0

To zależy od definicji klasy 'airport'. – molbdnilo

+0

lotnisko klasy { int planeCapacity; int acceptPlanesFrom; // i kilka innych intów publicznych: konstruktor .. metody dostępu }; To to. –

+0

Nie wiem, co sprawia, że ​​ludzie myślą, że twój plik wejściowy zawiera poprawne binarne zrzuty obiektów. Nie powiedziałeś tego. Większość odpowiedzi sprawia, że ​​IMO ryzykowne założenie. Przedstawiają również podejście, które było dość poprawne i używane w 'c', ale jest przestarzałe. Jeśli jesteś w 'C++' i zajmujesz się obiektami, to skończy się to bardzo źle wcześniej niż później. Najmniejsza zmiana w "lotnisku" złamie kompatybilność. Czy możesz powiedzieć, w jaki sposób jest tworzony plik wejściowy? Naprawdę nie możesz zaprojektować metody czytania bez znajomości jej przechowywania. Są silnie sprzężeni. Przydatna byłaby również definicja 'lotniska'. – luk32

Odpowiedz

4

Co próbujesz zrobić to serializacja. Ten sposób serializacji obiektów nie jest stabilny i bardzo zależy od tego, na jakim lotnisku jest. Lepiej używać jawnej serializacji.

Here to opis tego, czym jest serializacja i dlaczego jest tworzona w ten sposób.

W MessagePack typowy scenariusz serializacji-deserializacji będzie wyglądać następująco:

struct airport { 
std::string name; //you can name your airports here 
int planeCapacity; 
int acceptPlanesFrom; 
MSGPACK_DEFINE(name,planeCapacity,acceptPlanesFrom); 
}; 

...

// define your airports 
std::vector<airport> airports; 
airport a={"BLA",1,2}; 
airport b={"BLB",3,4}; 
airports.push_back(a); 
airports.push_back(b); 

// create a platform-independent byte sequence from your data 
msgpack::sbuffer sbuf; 
msgpack::pack(sbuf, airports) ; 
std::string data=sbuf.data();//you can write that into a file 

msgpack::unpacked msg; 
// get your data safely back 
msgpack::unpack(&msg, sbuf.data(), sbuf.size()); 
msgpack::object obj = msg.get(); 

std::cout<<obj<<std::endl; 

// now convert the bytes back to your objects 
std::vector<airport> read_airports; 
obj.convert(&read_airports); 
std::cout<<read_airports.size()<<std::endl; 

z wyjściem konsoli:

[["BLA", 1, 2], ["BLB", 3, 4]] 
2 
5

Jeśli masz pewność, że plik jest ważny, możesz po prostu użyć read(), aż dotrzesz do EOF. Każdy - z - da ci ważny obiekt airport.

Należy pamiętać, że przechowywanie binarnej "wartości" i obiektu spowoduje, że podczas ładowania załadowany obiekt będzie nieprawidłowy, jeśli zawiera wskaźniki - lub odniesienia.

EDYCJA: myfile.write((char*)&air,sizeof(airport); napisze treść obiektu air. Robiąc to, faktycznie piszesz obiekt, a nie wskaźnik.

+0

Witam bardzo dziękuję za twoje odpowiedź. Teraz rozumiem, że piszę wskaźniki do pliku i próbuję odczytać obiekt. Czy możesz mi wyjaśnić, jak napisać obiekt do pliku, a nie do wskaźnika. –

+0

potrzebna jest uporządkowana serializacja danych, a nie konstrukcji pamięci C++. –

+0

@DmitryLedentsov Tak, chyba że twoja klasa zawiera tylko podstawowe typy (lub obiektów, które same są podstawowych typów). – Xaqq

0
ofstream myfile; 

std::vector<airport> vec; 
myfile.open("rishab",ios::app||ios::binary); 
while(myfile.write(reinterpret_cast<char*>(&air),sizeof(airport)) != 0) 
    vec.push_back(air); 

myfile.close(); 

Teraz użyj vec do przetwarzania

+0

powinno być '(char *) i air'. – Xaqq

+0

@Xaqq zaktualizowany, dziękuje – P0W

+0

Czy to działa, ponieważ wysyłam wskaźnik do pliku, a nie obiekt? Przepraszam, tylko się pomieszam. A teraz będę musiał przejść przez wektor, prawda? –

0

Można zaprogramować go w takim stanie.

struct AirPort 
{ 
    int a; 
    int b; 
    int c; 
}; 
int main() 
{ 
    std::vector<AirPort> airportList; 
    FILE* fp = fopen(filename,"rb"); 
    if(NULL != fp) 
    { 
     while(!feof(fp)) 
     { 
      AirPort ap; 
      if (fread(&ap,sizeof(ap),1,fp)==1) 
      { 
       airportList.push_back(ap); 
      } 
     } 
    } 
    fclose(fp); 
    return 0; 
} 
+0

Cześć, dziękuję. Jednak jestem nieco zdezorientowany, ponieważ nie zrobiłem wiele wektorów i list. Jednak lotnisko jest klasą i teraz, po moim zrozumieniu, piszę wartość wskaźnika i próbuję odczytać obiekt, który oczywiście będzie nieistotny. Czy możesz mi pomóc z moim problemem? –

+0

Masz na myśli programowanie, jeśli nie używasz wektorów lub list? Nie rozumiem wyraźnie. Mój angielski nie jest zbyt dobry. Możesz mówić dokładnie, czego chcesz. Lepiej wstaw tutaj swój kod C++. – Keen