Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Zapis i odczyt na pliku binarnym.

Ostatnio zmodyfikowano 2015-03-20 21:21
Autor Wiadomość
Astacius
Temat założony przez niniejszego użytkownika
Zapis i odczyt na pliku binarnym.
» 2015-03-20 01:20:13
mam problem z tymi funkcjami, wszystko działa ok do momentu aż skompiluję program na nowo i spróbuję wczytać istniejące już rekordy z pliku, wypisują mi się wtedy jakieś losowe rzeczy, możecie mi z tym pomóc?

C/C++
void zapis( towary * tablica, int dane )
{
    ofstream plik;
    plik.open( "zadanie2.bin", ios::binary | ios_base::app );
    if( plik.good() == true )
         cout << "Udalo sie otworzyc plik." << endl;
   
    plik.write(( char * ) tablica, sizeof( tablica ) * dane );
    plik.close();
}

void odczyt( towary * tablica, int dane )
{
    ifstream plik;
    plik.open( "zadanie2.bin", ios::in | ios::binary | ios::ate );
    if( plik.good() == true )
         cout << "Udalo sie otworzyc plik." << endl;
   
    ifstream::pos_type wielkosc = plik.tellg();
   
    plik.read(( char * ) tablica,( wielkosc / sizeof( tablica ) ) );
    plik.close();
}

void odczyt_wybrany( towary * tablica, int dane )
{
    cout << "Ktory rekord chcesz otworzyc?" << endl;
    int rekord;
    do
    {
        cin >> rekord;
    } while( cin.fail() );
   
    ifstream plik;
    plik.open( "zadanie2.bin", ios::in | ios::binary | ios::ate );
    if( plik.good() == true )
         cout << "Udalo sie otworzyc plik." << endl;
   
    ifstream::pos_type wielkosc = plik.tellg();
   
    plik.read(( char * ) tablica,( wielkosc / sizeof( tablica ) ) );
    if( rekord <=( wielkosc / sizeof( tablica ) ) )
    {
        cout << "Nazwa towaru: " << tablica[ rekord ].towar << endl;
        cout << "ID: " << tablica[ rekord ].id << endl;
        cout << "Cena: " << tablica[ rekord ].cena << endl;
        cout << "Rodzaj: " << tablica[ rekord ].rodzaj << endl << endl;
    }
    else
         cout << "Nie ma takiego rekordu." << endl;
   
}
P-128791
darko202
» 2015-03-20 09:03:53
1.
>> wypisują mi się wtedy jakieś losowe rzeczy

*
towary* tablica
zastanów się czym jest i jaki ma rozmiar ?

**
ifstream::pos_type wielkosc = plik.tellg();
std::istream::tellg -> Returns the position of the current character in the input stream.
otwarłeś właśnie plik, więc gdzie możesz być

***
plik.read(( char * ) tablica,( wielkosc / sizeof( tablica ) ) );
w kontekście poprzednich pytań 
sizeof( tablica )   // ? ile to jest
( wielkosc / sizeof( tablica ) )  // ? podobnie

po powyższym read  - wypisz sobie co faktycznie przeczytałeś i porównaj z tym co chciałeś przeczytać


2.
void odczyt_wybrany( towary * tablica, int dane )
? gdzie używasz dane - jakiś miało to cel, a wydaje się zbędne
w dwóch funkcjach

3. możesz też umieścić więcej kodu
w szczególności dotyczącego tablicy na której operujesz
bo śmieci mogą też swiadczyć o przekraczaniu zakresu tablicy
ale tego nie widać w opublikowanym kodzie
P-128794
Astacius
Temat założony przez niniejszego użytkownika
» 2015-03-20 12:33:19
*
nie rozumiem zbytnio o co pytasz
**
myślałem że to pokaże mi wielkość pliku razem z ios::ate
***
wielkość jednego rekordu i ilość rekordów w pliku?
chyba nie powinienem był tam dzielić
2
pozostałości, już usunąłem
3
umieszczam całość

mam problem z tym że program nadpisuje ale plik niby zwiększa rozmiar, i nie mogę wczytywać rekordów po restarcie programu

C/C++
#include <iostream>
#include <string>
#include <conio.h>
#include <fstream>
#include <cstdlib>

using namespace std;


struct towary
{
    string towar;
    int cena;
    int id;
    string rodzaj;
};


void uzupelnij( towary * tablica, int dane )
{
    for( int i = 0; i < dane; i++ )
    {
        cout << "Wprowadz towar do bazy" << endl;
        cout << "Nazwa towaru: ";
        do
        {
            cin >> tablica[ i ].towar;
        } while( cin.fail() );
       
        cout << "ID towaru: ";
        do
        {
            cin >> tablica[ i ].id;
        } while( cin.fail() );
       
        cout << "Cena: ";
        do
        {
            cin >> tablica[ i ].cena;
        } while( cin.fail() );
       
        cout << "Rodzaj: ";
        do
        {
            cin >> tablica[ i ].rodzaj;
        } while( cin.fail() );
       
        cout << endl;
    } }

void wyszukaj( towary * tablica, int dane, string rodzaj_zadany )
{
    cout << "Rodzaj szukany: " << rodzaj_zadany << endl;
    for( int i = 0; i < dane; i++ )
    {
        if( tablica[ i ].rodzaj == rodzaj_zadany )
        {
            cout << "Rodzaj odnaleziony w rekordzie numer: " << i << endl;
            cout << "Nazwa: " << tablica[ i ].towar << endl;
            cout << "ID: " << tablica[ i ].id << endl;
            cout << "Cena: " << tablica[ i ].cena << endl;
            cout << "Rodzaj: " << tablica[ i ].rodzaj << endl;
        }
    }
}

void srednia( towary * tablica, int dane, string rodzaj_zadany )
{
    double srednia_cena = 0;
    int licznik = 0;
    for( int i = 0; i < dane; i++ )
    {
        if( tablica[ i ].rodzaj == rodzaj_zadany )
        {
            srednia_cena += tablica[ i ].cena;
            licznik++;
        }
    }
    cout << "Srednia cena: " <<( srednia_cena / licznik ) << endl;
}

void zapis( towary * tablica, int dane )
{
    ofstream plik;
    plik.open( "zadanie2.bin", ios::binary | ios_base::app );
    if( plik.good() == true )
         cout << "Udalo sie otworzyc plik." << endl << endl;
   
    plik.write(( char * ) tablica, sizeof( tablica ) * dane );
    plik.close();
}

void odczyt( towary * tablica )
{
    ifstream plik;
    plik.open( "zadanie2.bin", ios::in | ios::binary | ios::ate );
    if( plik.good() == true )
         cout << "Udalo sie otworzyc plik." << endl << endl;
   
    long wielkosc = plik.tellg();
    plik.seekg( 0 );
   
    plik.read(( char * ) tablica, wielkosc );
    plik.close();
}

void odczyt_wybrany( towary * tablica )
{
    cout << "Ktory rekord chcesz otworzyc?" << endl;
    int rekord;
    do
    {
        cin >> rekord;
    } while( cin.fail() );
   
    ifstream plik;
    plik.open( "zadanie2.bin", ios::in | ios::binary | ios::ate );
    if( plik.good() == true )
         cout << "Udalo sie otworzyc plik." << endl << endl;
   
    long wielkosc = plik.tellg();
    plik.seekg( 0 );
   
    plik.read(( char * ) tablica, wielkosc );
   
    if( rekord <=( wielkosc / sizeof( tablica ) ) )
    {
        cout << "Nazwa towaru: " << tablica[ rekord ].towar << endl;
        cout << "ID: " << tablica[ rekord ].id << endl;
        cout << "Cena: " << tablica[ rekord ].cena << endl;
        cout << "Rodzaj: " << tablica[ rekord ].rodzaj << endl << endl;
    }
    else
         cout << "Nie ma takiego rekordu." << endl;
   
}

int menu()
{
    int x;
    cout << "1. Wprowadz dane" << endl;
    cout << "2. Wyszukaj wszystkie rekordy o danym rodzaju" << endl;
    cout << "3. Srednia cena z wskazanego rodzaju towarow" << endl;
    cout << "4. Zapis do pliku" << endl;
    cout << "5. Odczyt pliku" << endl;
    cout << "6. Odczyt wybranego rekordu" << endl;
    cout << "7. Koniec" << endl;
    cin >> x;
    switch( x )
    {
    case 1: return 1;
    case 2: return 2;
    case 3: return 3;
    case 4: return 4;
    case 5: return 5;
    case 6: return 6;
    case 7: return 7;
    }
}

int main()
{
    cout << "Podaj ilosc rekordow" << endl;
    int dane;
    do {
        cin >> dane;
    } while( cin.fail() );
   
    cout << "Podaj szukany rodzaj" << endl;
    string rodzaj_zadany;
    do {
        cin >> rodzaj_zadany;
    } while( cin.fail() );
   
    towary * tablica = new towary[ dane ];
   
    do
    {
        switch( menu() )
        {
        case 1: uzupelnij( tablica, dane );
            break;
        case 2: wyszukaj( tablica, dane, rodzaj_zadany );
            break;
        case 3: srednia( tablica, dane, rodzaj_zadany );
            break;
        case 4: zapis( tablica, dane );
            break;
        case 5: odczyt( tablica );
            break;
        case 6: odczyt_wybrany( tablica );
            break;
        case 7: getch(); return 0;
        }
       
    } while( true );
   
    return 0;
}
P-128799
Monika90
» 2015-03-20 12:36:22
I tak czy siak, nie da się zapisywać struktur zawierających std::string takim sposobem, nawet gdybyś robił to prawidłowo, więc musisz wymyślić coś innego.
P-128800
Astacius
Temat założony przez niniejszego użytkownika
» 2015-03-20 12:50:08
a jakim sposobem mogę je zapisać żeby później nie było problemu z odczytaniem?

edit: zamieniłem stringi na chary, teraz po restarcie programu wczytuje mi poprawnie nazwę pierwszego produktu ale reszta rekordów to jakieś krzaczki

poprawiłem program jeszcze bardziej ale problem ten co wyżej, wczytuje się tylko nazwa pierwszego rekordu a reszta to krzaki

C/C++
#include <iostream>
#include <string>
#include <conio.h>
#include <fstream>
#include <cstdlib>

using namespace std;


struct towary
{
    char towar[ 40 ];
    int cena;
    int id;
    char rodzaj[ 40 ];
};


void uzupelnij( towary * tablica, int dane )
{
    for( int i = 0; i < dane; i++ )
    {
        cout << "Wprowadz towar do bazy" << endl;
        cout << "Nazwa towaru: ";
        do
        {
            cin.clear(); cin.sync();
            cin >> tablica[ i ].towar;
        } while( cin.fail() );
       
        cout << "ID towaru: ";
        do
        {
            cin.clear(); cin.sync();
            cin >> tablica[ i ].id;
        } while( cin.fail() );
       
        cout << "Cena: ";
        do
        {
            cin.clear(); cin.sync();
            cin >> tablica[ i ].cena;
        } while( cin.fail() );
       
        cout << "Rodzaj: ";
        do
        {
            cin.clear(); cin.sync();
            cin >> tablica[ i ].rodzaj;
        } while( cin.fail() );
       
        cout << endl;
    } }

void wyszukaj( towary * tablica, int dane )
{
    cout << "Podaj szukany rodzaj" << endl;
    char rodzaj_zadany[ 40 ];
    do {
        cin.clear(); cin.sync();
        cin >> rodzaj_zadany;
    } while( cin.fail() );
   
    cout << "Rodzaj szukany: " << rodzaj_zadany << endl;
    for( int i = 0; i < dane; i++ )
    {
        if( tablica[ i ].rodzaj == rodzaj_zadany )
        {
            cout << "Rodzaj odnaleziony w rekordzie numer: " << i << endl;
            cout << "Nazwa: " << tablica[ i ].towar << endl;
            cout << "ID: " << tablica[ i ].id << endl;
            cout << "Cena: " << tablica[ i ].cena << endl;
            cout << "Rodzaj: " << tablica[ i ].rodzaj << endl;
        }
    }
}

void srednia( towary * tablica, int dane )
{
    cout << "Podaj szukany rodzaj" << endl;
    char rodzaj_zadany[ 40 ];
    do {
        cin.clear(); cin.sync();
        cin >> rodzaj_zadany;
    } while( cin.fail() );
   
    double srednia_cena = 0;
    int licznik = 0;
    for( int i = 0; i < dane; i++ )
    {
        if( tablica[ i ].rodzaj == rodzaj_zadany )
        {
            srednia_cena += tablica[ i ].cena;
            licznik++;
        }
    }
    cout << "Srednia cena: " <<( srednia_cena / licznik ) << endl;
}

void zapis( towary * tablica, int dane )
{
    ofstream plik;
    plik.open( "zadanie2.bin", ios::binary | ios::app );
    if( plik.good() == true )
         cout << "Udalo sie otworzyc plik." << endl << endl;
   
    plik.write(( char * ) tablica, sizeof( tablica ) * dane );
    plik.close();
}

void odczyt( towary * tablica )
{
    ifstream plik;
    plik.open( "zadanie2.bin", ios::in | ios::binary | ios::ate );
    if( plik.good() == true )
         cout << "Udalo sie otworzyc plik." << endl << endl;
   
    long wielkosc = plik.tellg();
    long ilosc =( wielkosc / sizeof( tablica ) );
    plik.seekg( 0 );
   
    plik.read(( char * ) tablica, sizeof( tablica ) * ilosc );
    plik.close();
}

void odczyt_wybrany( towary * tablica )
{
    cout << "Ktory rekord chcesz otworzyc?" << endl;
    int rekord;
    do
    {
        cin >> rekord;
    } while( cin.fail() );
   
    ifstream plik;
    plik.open( "zadanie2.bin", ios::in | ios::binary | ios::ate );
    if( plik.good() == true )
         cout << "Udalo sie otworzyc plik." << endl << endl;
   
    long wielkosc = plik.tellg();
    long ilosc =( wielkosc / sizeof( tablica ) );
    plik.seekg( 0 );
   
    plik.read(( char * ) tablica, sizeof( tablica ) * ilosc );
   
    if( rekord <= ilosc )
    {
        cout << "Nazwa towaru: " << tablica[ rekord ].towar << endl;
        cout << "ID: " << tablica[ rekord ].id << endl;
        cout << "Cena: " << tablica[ rekord ].cena << endl;
        cout << "Rodzaj: " << tablica[ rekord ].rodzaj << endl << endl;
    }
    else
         cout << "Nie ma takiego rekordu." << endl;
   
}

int menu()
{
    int x;
    cout << "1. Wprowadz dane" << endl;
    cout << "2. Wyszukaj wszystkie rekordy o danym rodzaju" << endl;
    cout << "3. Srednia cena z wskazanego rodzaju towarow" << endl;
    cout << "4. Zapis do pliku" << endl;
    cout << "5. Odczyt pliku" << endl;
    cout << "6. Odczyt wybranego rekordu" << endl;
    cout << "7. Koniec" << endl;
    do
    {
        cin.clear(); cin.sync();
        cin >> x;
    } while( x > 7 || cin.fail() || x < 1 );
   
    switch( x )
    {
    case 1: return 1;
    case 2: return 2;
    case 3: return 3;
    case 4: return 4;
    case 5: return 5;
    case 6: return 6;
    case 7: return 7;
    }
}

int main()
{
    cout << "Podaj ilosc rekordow do wprowadzenia." << endl;
    int dane;
    do {
        cin.clear(); cin.sync();
        cin >> dane;
    } while( cin.fail() );
   
    towary * tablica = new towary[ dane ];
   
    do
    {
        switch( menu() )
        {
        case 1: uzupelnij( tablica, dane );
            break;
        case 2: wyszukaj( tablica, dane );
            break;
        case 3: srednia( tablica, dane );
            break;
        case 4: zapis( tablica, dane );
            break;
        case 5: odczyt( tablica );
            break;
        case 6: odczyt_wybrany( tablica );
            break;
        case 7: getch(); return 0;
        }
       
    } while( true );
   
    return 0;
}
P-128801
Monika90
» 2015-03-20 20:42:35
sizeof( tablica ) to jest rozmiar wskaźnika, a Ty potrzebujesz rozmiaru pojedynczego elementu tablicy
P-128831
Astacius
Temat założony przez niniejszego użytkownika
» 2015-03-20 21:21:27
więc jak to powinno wyglądać? wydawało mi się że to akurat jest dobrze
P-128834
« 1 »
  Strona 1 z 1