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

Zapisywanie danych z pliku...

Ostatnio zmodyfikowano 2009-10-16 18:34
Autor Wiadomość
driver1995
Temat założony przez niniejszego użytkownika
Zapisywanie danych z pliku...
» 2009-10-15 12:50:01
Witam... Kiedyś napisałem temat (http://forum.ddt.pl/?Tid=1013) o odczytywaniu danych z pliku...
I zgodnie z przykładem, jaki mi tam zaproponowano, chciałbym teraz np. zmienić te dane i zapisać nowe, nie zmieniają przy tym innych... Kod wygląda mniej więcej tak (do odczytywania):
C/C++
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>

using namespace std;

struct item
{
    string nazwa;
    double cena; //brzydko!
    unsigned int ilosc;
};

istream & operator >>( istream & str, item & obj )
{
    str >> obj.nazwa >> obj.cena >> obj.ilosc;
    return str;
}

ostream & operator <<( ostream & str, const item & obj )
{
    str << obj.nazwa << "\t" << obj.cena << "\t" << obj.ilosc << "\t";
    return str;
}

int main()
{
    ifstream plik( "a.txt" );
    if( plik.fail() )
    {
        cerr << "zuo przyszlo i otworzyc nie dalo...";
        return - 1;
    }
    vector < item > rzeczy;
    item temp;
    copy( istream_iterator < item >( plik ), istream_iterator < item >(), back_inserter( rzeczy ) );
    //mamy odczytane, siedzi w tablicy rzeczy
    //dostęp:
    //rzeczy[x].nazwa to nazwa
    //rzeczy[x].cena to cena
    //rzeczy[x].ilosc to ilosc
    //x to liczba całkowita dodatnia, MNIEJSZA NIŻ rzeczy.size()!
    //wypiszemy wszystko na stdout
    copy( rzeczy.begin(), rzeczy.end(), ostream_iterator < item >( cout, "\n" ) );
}
P-10909
DejaVu
» 2009-10-15 13:26:36
To wogóle działa...? :) nie jestem pewien czy std::string'a możesz sobie zapisać do pamięci w ten sposób. Jeśli łańcuch znaków jest dynamiczny to będziesz musiał zmienić wszystkie dane. Jeśli byłby to stały rozmiar struktury, tj.
C/C++
struct bleble
{
    char napis[ 20 ];
    double liczba;
    int costam;
}; //struct bleble
Mógłbyś ustalać numer elementu w pliku tak:
C/C++
int iRozmiar = sizeof( bleble );
int iPozycjaStartowa = indeks * iRozmiar;
Następnie wykonałbyś przesunięcie na iPozycjaStartowa' w pliku i zapisał iRozmiar' bajtów.
P-10910
driver1995
Temat założony przez niniejszego użytkownika
» 2009-10-15 13:28:06
No pewnie... A czemu ma nie działać :)
P-10911
DejaVu
» 2009-10-15 13:37:38
Wydaje mi się, że program, który przedstawiłeś zapisuje dane tekstowo, a nie binarnie, tak więc nie ma opcji wczytywania wybranego elementu i jego zapisywania. Kod ten pisał manfred, więc te szlaczki on najlepiej pojmuje :) Ja nie znam na tyle dobrze STL'a, żeby powiedzieć co dokładnie ten kod robi. Mogę się jedynie domyślać lub go po prostu skompilować (ale nie chce mi się ;p).
P-10912
driver1995
Temat założony przez niniejszego użytkownika
» 2009-10-15 14:19:35
ok... spróbuję tego sposobu, tylko jeszcze mam pytanie... Jak mam np. char napis[20]; i chcę zmienić ten napis na co innego, to jak to zrobić... Bo jak robię np. napis="blebleble" to nie wychodzi???

Edit:
Ale tego tego czegoś, co mi podałeś to nie rozumiem :/ Czym jest ten indeks i jak to zapisać.. Bo plik<<costam nie chce działać.. A jak robię write() to mi wyskakują błędy...
P-10916
Elaine
» 2009-10-15 15:02:00
C/C++
char foo[ 20 ];
strcpy( foo, "Ala zjadła kota." );

Kod ten pisał manfred, więc te szlaczki on najlepiej pojmuje
Zaraz szlaczki. To jest całkiem normalny kod C++, który nie używa niczego niezwykłego. Ale jedno muszę przyznać - autor musi być maniakiem STLa i standardofilem, żeby coś takiego zrobić, przecież zwykła pętla zrobi to samo, a jest kapkę czytelniejsza.

Hmmm... Jeśli chcesz użyć tego cyrku manfreda (@ten zuy, jeśli to czytasz: srx, nie jestem takim do końca nowym userem, pamiętam tamte czasy i wiem, jaki miałeś nick), to wyglądałoby to jakoś tak:
1. Dodanie nowego przedmiotu:
C/C++
item foo;
foo.nazwa = "Banan";
foo.cena = 4.20;
foo.ilosc = 11;
rzeczy.push_back( foo );
2. Zmiana istniejącego:
C/C++
int i = 8; // indeks elementu do zmiany
rzeczy[ i ].nazwa = "Gruszka";
// analogicznie się zmienia pola cena i ilosc
3. Zapisanie tego do pliku:
C/C++
// ech, musiałem sobie odświeżyć wiedzę o iostreamsach,
// bo na codzień używam wygodnych rzeczy (czyt. I/O pamiętające czasy C)
ofstream file( "sth.txt" );
if( file.fail() )
{
    // ups, pliku się nie udało otworzyć, zakodź sobie to sam
}
// dobra, teraz istotna sprawa - robimy to tak, jak odczyt, czy normalnie?
// jak chcesz normalnie (bez kombinowania z iteratorami strumieni),
// to zmień to 0 na 1
#if 0
for( size_t i = 0; i < rzeczy.size(); ++i )
{
    file << rzeczy[ i ] << '\n';
}
#else
copy( rzeczy.begin(), rzeczy.end(), ostream_iterator < item >( file, "\n" ) );
#endif
P-10917
driver1995
Temat założony przez niniejszego użytkownika
» 2009-10-15 18:52:09
Dzięki wielkie za pomoc... A jeszcze mam takie pytanie... Czemu sądzicie, że kod manfreda jest nieczytelny?? Co jest w nim nie tak? I jak jest prościej? :)
P-10920
DejaVu
» 2009-10-15 19:21:45
copy( istream_iterator < item >( plik ), istream_iterator < item >(), back_inserter( rzeczy ) );
Czy powyższa linijka jest dla Ciebie oczywista? :) Jeśli tak to gratuluję tak dobrej znajomości STL'a :) Ja nigdy nie używałem szablonu istream_iterator i back_inserter'a.
P-10922
« 1 » 2
  Strona 1 z 2 Następna strona