gmysu Opublikowano 2 Września 2011 Udostępnij Opublikowano 2 Września 2011 Mam sobie taki kod w C++: GML #include <iostream> #include <fstream> #include <string> using namespace std; struct book { string strTytul; string strAutor; int intRok; }; book* create_table(int rozmiar) { book tablica [rozmiar]; fstream plik; plik.open("baza.dat",ios::binary|ios::in); plik.seekp(ios_base::beg); plik.read(reinterpret_cast<char*>(&tablica),sizeof(*tablica)); plik.close(); return tablica; } int save_table(book* table) { fstream plik; plik.open("baza.dat",ios::out|ios::binary); plik.write(reinterpret_cast<char*>(table),sizeof(*table)); plik.close(); return 0; } int main() { int opcja = 0; int rozmiar_tablicy = 1500; book* tablica; tablica = create_table(rozmiar_tablicy); while(opcja!=3) { cout << "Wybierz akcje:" << endl; cout << "1 - Dodaj wpis" << endl; cout << "2 - Czytaj 0" << endl; cout << "3 - Exit" << endl; cin >> opcja; switch(opcja) { case 1: { tablica ->strTytul = "Suicide for dummies"; tablica ->strAutor = "Ktostam"; tablica ->intRok = 2532; cout << "Dodano ksiazke!" << endl; } break; case 2: { int poz = 0; cout << "Podaj numer pozycji do wyswietlenia: "; cin >> poz; cout << (tablica + poz)->strTytul << endl; } break; }; } save_table(tablica); return 0; } Kompilator nie wypluwa żadnych błędów, a mimo to całość wykrzacza się po uruchomieniu. Problem leży prawdopodobnie w odczycie, bo zanim plik zostanie utworzony po raz pierwszy (i nie ma jeszcze niczego do odczytu) wszystko przynajmniej w teorii działa. Pomocy! Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
PsichiX Opublikowano 2 Września 2011 Udostępnij Opublikowano 2 Września 2011 pokaż log debugu IDE, oraz sprawdź w calstacku na czym wywala dokładnie i pokaż nam to Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
gmysu Opublikowano 2 Września 2011 Autor Udostępnij Opublikowano 2 Września 2011 pokaż log debugu IDE, oraz sprawdź w calstacku na czym wywala dokładnie i pokaż nam to Callstack i debugger są puste, nie zwracają żadnych błędów. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
PsichiX Opublikowano 2 Września 2011 Udostępnij Opublikowano 2 Września 2011 wykrzacza się po uruchomieniu wykrzaczając się, zatrzymuje się w danym miejscu w programie, to miejsce pokazuje callstack. jak pokazuje się komunikat access violation, lub cokolwiek z przyciskami "contnue" i "break", to klikasz jdno, albo drugie i po tym masz w callstacku na samym początku pokazane, w jakiej funkcji się wysypało, ponadto w kodzie zaznacza strzałką linię, gdzie został przerwany program i nastąpiło wykrzaczenie (mowa o visual c++, jak masz inne ide to powinno być podobnie, byle nie devcpp, bo jak używasz devcpp, to nie pomogę - to jest IDE odpowiednie do śmietnika). Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
gmysu Opublikowano 2 Września 2011 Autor Udostępnij Opublikowano 2 Września 2011 Może źle się wyraziłem. Program kompiluje się i uruchamia bez problemów. Dopiero po udanym uruchomieniu pojawia się znajome wszystkim okno "program zakończył pracę blablabla". Jak już mówiłem, debugger i callstack są puste. @Edit: IDE - code::blocks Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Lunatyk Opublikowano 2 Września 2011 Udostępnij Opublikowano 2 Września 2011 Po wrzuceniu tego kodu kompilator wywala mi to PsychiX: 1>------ Build started: Project: test, Configuration: Debug Win32 ------ 1>Build started 2011-09-02 18:51:04. 1>PrepareForBuild: 1> Creating directory "D:\Projekty\Programy\Game\test\Debug\". 1>InitializeBuildStatus: 1> Creating "Debug\test.unsuccessfulbuild" because "AlwaysCreate" was specified. 1>ClCompile: 1> main.cpp 1>d:\projekty\programy\game\test\test\main.cpp(16): error C2057: expected constant expression 1>d:\projekty\programy\game\test\test\main.cpp(16): error C2466: cannot allocate an array of constant size 0 1>d:\projekty\programy\game\test\test\main.cpp(16): error C2133: 'tablica' : unknown size 1>d:\projekty\programy\game\test\test\main.cpp(22): warning C4172: returning address of local variable or temporary 1> 1>Build FAILED. 1> 1>Time Elapsed 00:00:04.14 ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
ediepl Opublikowano 2 Września 2011 Udostępnij Opublikowano 2 Września 2011 Spróbuj zamienić book tablica [rozmiar]; na book* tablica = new book[rozmiar]; Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
gmysu Opublikowano 2 Września 2011 Autor Udostępnij Opublikowano 2 Września 2011 Spróbuj zamienić book tablica [rozmiar]; na book* tablica = new book[rozmiar]; Wczoraj nie chciało działać z dynamiczną alokacją, dlatego próbowałem dzisiaj z powyższym. Sec. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
PsichiX Opublikowano 2 Września 2011 Udostępnij Opublikowano 2 Września 2011 ediepl podal wlasciwe rozwiazanie. nie mozna alokowac tablicy statycznej ze zmienna jako jej rozmiaru. tak tylko mozna poprzez dynamiczna alokacje Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
gmysu Opublikowano 2 Września 2011 Autor Udostępnij Opublikowano 2 Września 2011 ediepl podal wlasciwe rozwiazanie. nie mozna alokowac tablicy statycznej ze zmienna jako jej rozmiaru. tak tylko mozna poprzez dynamiczna alokacje Problem pozostaje ten sam, z tym że teraz nie działa sam zapis. Czy zamiast grzebać w tym srednio udanym tworze, ktoś mógłby napisac program który zapisuje do tablice struktur do pliku binarnego a nastepnie odczytuje je? Bede wdzieczny. GML #include <iostream> #include <fstream> #include <string> using namespace std; struct book { string strTytul; string strAutor; int intRok; }; book* create_table(int rozmiar) { book* tablica; tablica = new book [rozmiar]; fstream plik; plik.open("baza.dat",ios::binary|ios::in); plik.seekp(ios_base::beg); plik.read(reinterpret_cast<char*>(tablica),sizeof(*tablica)); plik.close(); return tablica; } int save_table(book* table) { fstream plik; plik.open("baza.dat",ios::out|ios::binary); plik.write(reinterpret_cast<char*>(table),sizeof(book)*1500); plik.close(); return 0; } int main() { int opcja = 0; int rozmiar_tablicy = 1500; book* tablica; tablica = create_table(rozmiar_tablicy); while(opcja!=3) { cout << "Wybierz akcje:" << endl; cout << "1 - Dodaj wpis" << endl; cout << "2 - Czytaj 0" << endl; cout << "3 - Exit" << endl; cin >> opcja; switch(opcja) { case 1: { tablica ->strTytul = "Suicide for dummies"; tablica ->strAutor = "Ktostam"; tablica ->intRok = 2532; cout << "Dodano ksiazke!" << endl; } break; case 2: { int poz = 0; cout << "Podaj numer pozycji do wyswietlenia: "; cin >> poz; cout << (tablica + poz)->strTytul << endl; } break; }; } save_table(tablica); delete[] tablica; return 0; } Powyzszy kod to to co mam teraz. Jesli okaze sie ze cudze rozwiazanie tez nie bedzie dzialac, zmieniam srodowisko. Szkoda, bo liczylem na to ze nie bede zmuszony korzystac z visual c++. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
ediepl Opublikowano 2 Września 2011 Udostępnij Opublikowano 2 Września 2011 Jaki kompilator? Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
gmysu Opublikowano 2 Września 2011 Autor Udostępnij Opublikowano 2 Września 2011 MinGW Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Will Opublikowano 2 Września 2011 Udostępnij Opublikowano 2 Września 2011 Pomyśl, jak możesz tak zapisywać strukturę, która ma taką budowę? To nie jest POD więc nie ma prawa działać. Użyj takiej: struct Book { char tytul[256]; char autor[256]; int rok; }; edit: oczywiście kod ma więcej błędów, przede wszystkim trzeba sprawdzać co zwraca nam dana funkcja. Np: plik.read(reinterpret_cast<char*>(tablica),sizeof(*tablica)); Zapewniam Cię, że to nie będzie działać tak jak tego oczekujesz(o ile dobrze zrozumiałem co chcesz tu zrobić). Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
gmysu Opublikowano 2 Września 2011 Autor Udostępnij Opublikowano 2 Września 2011 Pomyśl, jak możesz tak zapisywać strukturę, która ma taką budowę? To nie jest POD więc nie ma prawa działać. Użyj takiej: struct Book { char tytul[256]; char autor[256]; int rok; }; edit: oczywiście kod ma więcej błędów, przede wszystkim trzeba sprawdzać co zwraca nam dana funkcja. Np: plik.read(reinterpret_cast<char*>(tablica),sizeof(*tablica)); Zapewniam Cię, że to nie będzie działać tak jak tego oczekujesz(o ile dobrze zrozumiałem co chcesz tu zrobić). Po modyfikacji struktury coś się wreszcie ruszyło, tj. nie wyskakuje już access violation. Nie mialem pojecia ze string to typ ktorego nie da sie wykorzystac w ten sposob:(. Mam 1500 elementow w tablicy, a plik wynikowy (baza.dat ) nadal ma poniżej 1kb. Jak powinno wyglądać poprawne rzutowanie w tym wypadku? Dzięki! Edit: wygląda na to że działa. Dzięki raz jeszcze. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Will Opublikowano 2 Września 2011 Udostępnij Opublikowano 2 Września 2011 Przede wszystkim sprawdzaj ile danych się wczytało i ile zapisało. np: plik.read(reinterpret_cast<char*>(tablica),sizeof(*tablica)); -> sizeof(*tablica) wczyta tylko jeden element. Tutaj jeszcze jakieś cuda wyczyniasz: tablica ->strTytul = "Suicide for dummies"; tablica ->strAutor = "Ktostam"; tablica ->intRok = 2532; Masz wskaźnik na tablice, nie na pojedynczy obiekt. Przykład poprawnego zapisu/wczytania: #include <iostream> #include <fstream> #include <string> using namespace std; struct book { char strTytul[256]; char strAutor[256]; int intRok; }; int main() { book* arr=new book[1500]; fstream plik("data.txt",ios::binary|ios::out); arr[5].intRok=3456; arr[7].intRok=345; arr[1234].intRok=12; plik.write((char*)&arr[0],1500*sizeof(book)); plik.close(); plik.open("data.txt",ios::binary|ios::in); book* arr2=new book[1500]; plik.read((char*)&arr2[0],1500*sizeof(book)); cout<<"5: "<<arr2[5].intRok<<"\n"; cout<<"7: "<<arr2[7].intRok<<"\n"; cout<<"1234: "<<arr2[1234].intRok<<"\n"; delete []arr; delete [] arr2; int k=0; cin>>k; } Zmienione dane po wczytaniu są tam gdzie powinny czyli działa, rozpisać już możesz sobie sam. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Rekomendowane odpowiedzi
Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto
Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.
Zarejestruj nowe konto
Załóż nowe konto. To bardzo proste!
Zarejestruj sięZaloguj się
Posiadasz już konto? Zaloguj się poniżej.
Zaloguj się