Problem z fstream

dział ogólny

Problem z fstream

Nowy postprzez Miroo_007 » sobota, 30 maja 2009, 10:21

Mam problem z zapisem danych do pliku już istniejącego i mającego już jakieś dane. Zapisując dane do pliku usuwają mi się dane, które tam już są. Tak jakby działał specyfikator ios::trunc choć używam ios:ate. Oto kod:
Kod: Zaznacz cały
TSzablon_zapis zapis;
fstream plik;
try {
      plik.open(opcje.sciezka_schematow_email.c_str(), ios::out | ios::ate | ios::binary);
      plik.seekp(0, ios::end);
      int wielkosc_pliku = plik.tellp(); //w celach pogladowych
      plik.seekp(i * sizeof(TSzablon_zapis));
      plik.write((char*)&zapis,sizeof(TSzablon_zapis));
__finally {
      plik.close();
}

Otwierając plik do zapisu zmienna wielkosc_pliku zawsze równa się zero. Jeżeli otworze plik do odczytu to wartość jest poprawna (różna od zera).
Avatar użytkownika
Miroo_007
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): sobota, 18 października 2008, 10:49
Lokalizacja: Rzeszów
Podziękował : 0
Otrzymał podziękowań: 0
    NieznanyNieznana

Re: Problem z fstream

Nowy postprzez polymorphism » sobota, 30 maja 2009, 13:58

A ios::app złe?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Problem z fstream

Nowy postprzez Miroo_007 » sobota, 30 maja 2009, 14:08

Z ios::app też usuwa mi wcześniejsze dane zostawiając puste miejsce.
Avatar użytkownika
Miroo_007
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): sobota, 18 października 2008, 10:49
Lokalizacja: Rzeszów
Podziękował : 0
Otrzymał podziękowań: 0
    NieznanyNieznana

Re: Problem z fstream

Nowy postprzez polymorphism » sobota, 30 maja 2009, 14:17

Hmm, nie powinno. Spróbuj może z ofstream - nie sądzę, żeby to coś dało, ale kto wie...
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Problem z fstream

Nowy postprzez Miroo_007 » sobota, 30 maja 2009, 14:20

Może to być błąd C++ Builder 2007?
Avatar użytkownika
Miroo_007
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): sobota, 18 października 2008, 10:49
Lokalizacja: Rzeszów
Podziękował : 0
Otrzymał podziękowań: 0
    NieznanyNieznana

Re: Problem z fstream

Nowy postprzez Miroo_007 » sobota, 30 maja 2009, 14:28

Spróbuj może z ofstream - nie sądzę, żeby to coś dało, ale kto wie...

Nie pomogło. Czy da się usunąć ręcznie specyfikator ios::trunc? Wiem, że usuwa się specyfikatory błędu a można specyfikator otwarcia?
Avatar użytkownika
Miroo_007
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): sobota, 18 października 2008, 10:49
Lokalizacja: Rzeszów
Podziękował : 0
Otrzymał podziękowań: 0
    NieznanyNieznana

Re: Problem z fstream

Nowy postprzez polymorphism » sobota, 30 maja 2009, 15:28

Może to być błąd C++ Builder 2007?

Może...

Spróbuj jeszcze z taką wiązanką:
Kod: Zaznacz cały
ios::in | ios::out | ios::ate | ios::binary

flaga in powinna zablokować czyszczenie pliku.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Problem z fstream

Nowy postprzez Miroo_007 » sobota, 30 maja 2009, 17:03

Nic to nie zmienia. Przerobię to na TFileStream bo już mnie trafia z tym. Straciłem przez to 2 dni.
Avatar użytkownika
Miroo_007
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): sobota, 18 października 2008, 10:49
Lokalizacja: Rzeszów
Podziękował : 0
Otrzymał podziękowań: 0
    NieznanyNieznana

Re: Problem z fstream

Nowy postprzez simekone » sobota, 30 maja 2009, 17:20

Spróbuj użyć zamiast
Kod: Zaznacz cały
c_str()
funkcji
Kod: Zaznacz cały
t_str()
dodaj też parametry zapisu
Kod: Zaznacz cały
ios::in | ios::app
Avatar użytkownika
simekone
Bladawiec
Bladawiec
 
Posty: 31
Dołączył(a): środa, 25 marca 2009, 13:27
Podziękował : 1
Otrzymał podziękowań: 0
Kompilator: CodeGear C++ Builder 2009
    NieznanyNieznana

Re: Problem z fstream

Nowy postprzez Miroo_007 » sobota, 30 maja 2009, 17:35

simekone napisał(a):Spróbuj użyć zamiast
Kod: Zaznacz cały
c_str()

funkcji
Kod: Zaznacz cały
t_str()

To nic nie wnosi do sprawy. Używam kompilatora C++ Builder 2007, a Ty mówisz o C++ Builder 2009.
Ten zapis powoduje błąd:
Kod: Zaznacz cały
fstream plik;
try {
      plik.open(sciezka.c_str(), ios::in | ios::out | ios::binary | ios::app);
      if(plik.good()) {
         plik.write((char*)&zapis, sizeof(TSzablon_zapis));
         plik.close();
      }
      else return;
} catch (Exception &e) {
   blad.Raport(e.Message);
}
Avatar użytkownika
Miroo_007
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): sobota, 18 października 2008, 10:49
Lokalizacja: Rzeszów
Podziękował : 0
Otrzymał podziękowań: 0
    NieznanyNieznana

Re: Problem z fstream

Nowy postprzez polymorphism » sobota, 30 maja 2009, 18:01

Nic to nie zmienia.

No to być może jest jakiś błąd w strumieniu - w obu przypadkach, które podałem, strumień nie czyścił mi pliku (testowałem to na GCC).

Ten zapis powoduje błąd:

Jaki błąd?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Problem z fstream

Nowy postprzez Cyfrowy Baron » niedziela, 31 maja 2009, 11:36

plik.open(sciezka.c_str(), ios::in | ios::out | ios::binary | ios::app);


Nie można jednocześnie używać operatora ios::in (odczyt danych) i ios::out (zapis danych).

Operatorem umożliwiającym dopisanie danych do pliku jest ios::app.
Używasz biblioteki fstream, ale dla odczytu danych stosujemy klasę ifstream, a do zapisu ofstream, dlatego Tój kod powinien wyglądać tak:

Kod: Zaznacz cały
  TSzablon_zapis zapis;
    ofstream plik;
    try {
          plik.open(opcje.sciezka_schematow_email.c_str(), ios::out | ios::app | ios::binary);
          plik.seekp(0, ios::end);
          int wielkosc_pliku = plik.tellp(); //w celach pogladowych
          plik.seekp(i * sizeof(TSzablon_zapis));
          plik.write((char*)&zapis,sizeof(TSzablon_zapis));
       }
    __finally {
          plik.close();
    }


Problemem wynika prawdopodobnie z klasy TSzablon_zapisu.

Przeprowadziłem testy z Twoim kodem u siebie w środowisku C++ BUilder 2007. Nie znam Twojej struktury TSzablon_zapis, więc użyłem własnej przykładowej:

► 


i u mnie to działa, dane są dopisywane na końcu pliku, a ten fragment kodu:

plik.seekp(i * sizeof(Baza));

jest zbędny, gdyż argument ios::app odpowiada za dopisywanie danych zawsze na końcu pliku.

podobnie jak ten fragment:

plik.seekp(0, ios::end);

chyba że chcesz pobierać rozmiar pliku.


Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Problem z fstream

Nowy postprzez polymorphism » niedziela, 31 maja 2009, 11:48

Cyfrowy Baron napisał(a):Nie można jednocześnie używać operatora ios::in (odczyt danych) i ios::out (zapis danych).

Oczywiście, że można. Odsyłam chociażby do tego.

______________
PS. ios::in, ios::out itd. nie są operatorami - to flagi, zwykłe wartości liczbowe (enum), a fstream nie jest biblioteką, tylko klasą pochodną od iostream.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Problem z fstream

Nowy postprzez Miroo_007 » niedziela, 31 maja 2009, 12:40

Cyfrowy Baron napisał(a):Problemem wynika prawdopodobnie z klasy TSzablon_zapisu.

W programie operuje na klasie TSzablon:
Kod: Zaznacz cały
class TSzablon {
   public:
      AnsiString         tytul_szablonu,
                  tytul_wiadomosci,
                  sciezka_szablonu;
      bool            szablon_listy,
                  szablon_email,
                  szablon_SMS;
      TStringList      *Tresc_wiadomosci;
      void            Zapisz_szablon(TSzablon &lokalny, int i=0);
      void            Dodaj_szablon(TSzablon &lokalny);
      bool            Wczytaj_szablon(AnsiString sciezka,int i=0);
      TSzablon();
      ~TSzablon();
};

Do zapisywania wykorzystuje strukturę TSzablon_zapis:
Kod: Zaznacz cały
struct TSzablon_zapis {
      char            tytul_szablonu[100],
                  tytul_wiadomosci[300];
      bool            szablon_listy,
                  szablon_email,
                  szablon_SMS;
      char            Tresc_wiadomosci[2000];
};

Problem jest w funkcji TSzablon::Dodaj_szablon():
Kod: Zaznacz cały
void TSzablon::Dodaj_szablon(TSzablon &lokalny) {
   TSzablon_zapis zapis;
   strcpy(zapis.tytul_szablonu,    lokalny.tytul_szablonu.c_str());
   strcpy(zapis.tytul_wiadomosci,    lokalny.tytul_wiadomosci.c_str());
   strcpy(zapis.Tresc_wiadomosci,    lokalny.Tresc_wiadomosci->Text.c_str());
   zapis.szablon_listy          = lokalny.szablon_listy;
   zapis.szablon_email          = lokalny.szablon_email;
   zapis.szablon_SMS         = lokalny.szablon_SMS;
   AnsiString sciezka;
   if(lokalny.szablon_listy) sciezka    = opcje.sciezka_szablonow_listy;
   if(lokalny.szablon_email) sciezka    = opcje.sciezka_szablonow_email;
   if(lokalny.szablon_SMS) sciezka      = opcje.sciezka_szablonow_SMS;
   ofstream plik;
   try {
      plik.open(sciezka.c_str(), ios::out | ios::binary | ios::app);
      if(plik.good()) {
         plik.write((char*)&zapis, sizeof(TSzablon_zapis));
         plik.close();
      }
      else return;
   } catch (Exception &e) {
      blad.Raport(e.Message);
   }
   try {
      plik.open(sciezka.c_str(), ios::in | ios::binary);
      if(plik.good()) {
         plik.seekg(0, ios::end);
         int w = plik.tellg();
         if(zapis.szablon_listy) opcje.liczba_szablonow_listy = w    / sizeof(TSzablon_zapis);
         if(zapis.szablon_email) opcje.liczba_szablonow_email = w    / sizeof(TSzablon_zapis);
         if(zapis.szablon_SMS)    opcje.liczba_szablonow_SMS = w / sizeof(TSzablon_zapis);
         plik.close();
      }
   } catch (Exception &e) {
      blad.Raport(e.Message);
   } 
}

W Symfonii C++ jest napisane: tom 3, str.644 (dotyczy funkcji write):
Podobnie jak przy funkcji read, także i tutaj dodam, że jeśli program ma wykonywać wyjątkowo wiele operacji pisania binarnego - dobrze jest rozważyć posłużenie się klasą streambuf i jej pochodnymi.
Avatar użytkownika
Miroo_007
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): sobota, 18 października 2008, 10:49
Lokalizacja: Rzeszów
Podziękował : 0
Otrzymał podziękowań: 0
    NieznanyNieznana

Re: Problem z fstream

Nowy postprzez polymorphism » niedziela, 31 maja 2009, 12:58

Kod: Zaznacz cały
ofstream plik;

...

try
{
   plik.open(sciezka.c_str(), ios::in | ios::binary);
   if(plik.good())
   {
      plik.seekg(0, ios::end);
      
      int w = plik.tellg();
      
      ...
   }
   ...
}

Od kiedy to ostream ma takie metody jak seekg i tellg? No i po co te bloki try...catch?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Następna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 8 gości