Problem z fstream

dział ogólny

Re: Problem z fstream

Nowy postprzez Miroo_007 » niedziela, 31 maja 2009, 13:19

Sorry. Przerobiłem ten kod wstawiając do tego forum, a nie patrząc na cały kod. Tak powinno być:
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;
   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);
   }
   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);
   } 
}
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, 14:00

Poza paroma bezsensami nie widzę błędów. Z tymi flagami powinno być ok, a jeśli nie jest, najwidoczniej implementacja strumieni jest zjeb... lub o czymś nie mówisz.
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, 14:12

Przerobiłem kod ale jest to samo. Czeka mnie analiza całego programu. O jakich bezsensach mówisz?
Kod: Zaznacz cały
try {
      try {
         if(FileExists(sciezka)) {
            plik = new TFileStream(sciezka, Idobjs::fmOpenWrite);
            plik->Seek(0, soFromEnd);
         }
         else plik = new TFileStream(sciezka, Idobjs::fmCreate);
         plik->Write(&zapis,sizeof(TSzablon_zapis));      
      } catch (Exception &e) {
         blad.Raport(e.Message);
      }
      
   } __finally {
      delete plik;
   }
   try {
      try {
         plik = new TFileStream(sciezka, Idobjs::fmOpenRead);
         int w = plik->Size;
         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);
      } catch (Exception &e) {
         blad.Raport(e.Message);
      }
   } __finally {
      delete plik;
   }
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 » niedziela, 31 maja 2009, 14:42

Wreszcie doszedłem do rozwiązania tego problemu. Miałem błąd przy wyświetlaniu tych szablonów.
polymorphism napisał(a):Poza paroma bezsensami nie widzę błędów.

Możesz wskazać, które są bezsensowne. Dopiero uczę się programować...
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, 15:22

  • bloki try...catch w przypadku standardowych strumieni są zbyteczne, o ile nie ustawisz zgłaszania błędów przez wyjątki - vide metoda ios::exceptions. Domyślnie strumienie nie rzucają wyjątków.
  • dajesz dwa razy bloki try catch, zamiast dać wszystko w jednym.
  • Kod: Zaznacz cały
    if(plik.good())
    {
        plik.write((char*)&zapis, sizeof(TSzablon_zapis));
        plik.close();
    }
    else return;

    można tak:
    Kod: Zaznacz cały
    if(!plik.good()) return;
    plik.write((char*)&zapis, sizeof(TSzablon_zapis));
    plik.close();

    wiem wiem, czepiam się, ale takie drobiazgi znacznie poprawiają czytelność kodu, a to jest ważne.
  • otwierasz dwa razy ten sam plik (strumień), zamiast otworzyć raz, w trybie in/out.
  • nie wydaje ci się, że tworzenie nowej struktury (TSzablon_zapis) tylko po to, żeby zapisać inną, już istniejącą strukturę (TSzablon) nie ma sensu i niepotrzebnie zaśmieca przestrzeń nazw? *
___________________
* oczywiście nie możesz zapisać TSzablon metodą write, ale nie musisz przepisywać wszystkiego z tej struktury do innej, tylko po to żeby... co? raz wywołać write? Jak wywołasz więcej, nic się nie stanie. Zresztą twoja metoda ma dwa zasadnicze błędy: jest nieoptymalna pamięciowo (Tresc_wiadomosci - 2KB) i zupełnie ignorujesz takie coś jak wyrównanie struktur (alignment) - struktury, które zapisujesz do pliku, powinny być wyrównane do jednego bajta.
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, 15:24

Od kiedy to ostream ma takie metody jak seekg i tellg?


ofstream

Nie wiem od kiedy, ale faktem jest że ma, może są zawarte w bibliotece fstream.h.

Kod, który zamieściłem w poradzie sprawdziłem, użyłem w nim metod które negujesz, a mimo to kompilator nie zwrócił błędu i kod działa prawidłowo.




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.


można gdy używasz klasy fstream, ale nie można gdy używasz klasy ofstream, dla ofstream jest ios::out, a dla ifstream ios::in



Jeżeli tworzysz aplikację opartą o biblioteki VCL lepiej jest używać (moim zdaniem) klasy TFileStream, jest (moim zdaniem) bardziej funkcjonalna, elastyczna i łatwiej nią zarządzać.
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 Miroo_007 » niedziela, 31 maja 2009, 15:39

polymorphism napisał(a):dajesz dwa razy bloki try catch, zamiast dać wszystko w jednym.
polymorphism napisał(a):otwierasz dwa razy ten sam plik (strumień), zamiast otworzyć raz, w trybie in/out.

Kod: Zaznacz cały
TFileStream *plik;
   try {
      try {
         if(FileExists(sciezka)) {
            plik = new TFileStream(sciezka, Idobjs::fmOpenReadWrite);
            plik->Seek(0, soFromEnd);
         }
         else plik = new TFileStream(sciezka, Idobjs::fmCreate);
         plik->Write(&zapis,sizeof(TSzablon_zapis));   
         int w = plik->Size;
         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);   
      } catch (Exception &e) {
         blad.Raport(e.Message);
      }
      
   } __finally {
      delete plik;
   }

polymorphism napisał(a):nie wydaje ci się, że tworzenie nowej struktury (TSzablon_zapis) tylko po to, żeby zapisać inną, już istniejącą strukturę (TSzablon) nie ma sensu i niepotrzebnie zaśmieca przestrzeń nazw? *

Kod: Zaznacz cały
class TSzablon {
      struct TSzablon_zapis {
         char         tytul_szablonu[100],
                     tytul_wiadomosci[300];
         bool         szablon_listy,
                     szablon_email,
                     szablon_SMS;
         char         Tresc_wiadomosci[2000];
      };
   public:
      ...
      TSzablon_zapis      zapis;
      ...
};

polymorphism napisał(a):wyrównanie struktur (alignment) - struktury, które zapisujesz do pliku, powinny być wyrównane do jednego bajta.

Na czym to polega? Nie słyszałem o tym jeszcze.
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, 16:26

Nie wiem od kiedy, ale faktem jest że ma, może są zawarte w bibliotece fstream.h.

W nagłówku to one mogą być, bo jest tam klasa fstream, która dziedziczy pośrednio po istream, a ta posiada metody tellg i seekg (-g od get). ofstream, a tej klasy użył Miroo_007, nie posiada takich metod, bo dziedziczy tylko po ostream, która posiada metody tellp i seekp (-p od put).

ale nie można gdy używasz klasy ofstream, dla ofstream jest ios::out, a dla ifstream ios::in

No u mnie działa z flagą in na strumieniu wyjściowym. Ale pewny nie jestem, czy to zawsze będzie działać... choć nigdzie nie zauważyłem jakichś jednoznacznych zakazów używania tej flagi w stosunku do strumieni wyjściowych.
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 polymorphism » niedziela, 31 maja 2009, 16:53

Na czym to polega?

Data structure alignment
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, 18:07

ofstream, a tej klasy użył Miroo_007, nie posiada takich metod, bo dziedziczy tylko po ostream, która posiada metody tellp i seekp (-p od put).


więc jak wyjaśnisz fakt, że ja użyłem klasy ofstream ze wspomnianymi funkcjami kod działa prawidłowo:

Kod: Zaznacz cały
struct Baza
{
char Name[5][250];
char Mark[5][50];
float Cost[5];
};

void __fastcall TForm1::Button1Click(TObject *Sender)
{
Baza Hard;

sprintf(Hard.Name[0], "%s", "Bear Paw 1200 TA");
sprintf(Hard.Mark[0], "%s", "Skaner");
Hard.Cost[0] = 350;

sprintf(Hard.Name[1], "%s", "ImageQuest Q770");
sprintf(Hard.Mark[1], "%s", "Monitor");
Hard.Cost[1] = 800;

sprintf(Hard.Name[2], "%s", "Tracer TRK 21MTT");
sprintf(Hard.Mark[2], "%s", "Klawiatura");
Hard.Cost[2] = 187;

sprintf(Hard.Name[3], "%s", "FlashDisk");
sprintf(Hard.Mark[3], "%s", "Napęd Dyskowy USB Flash");
Hard.Cost[3] = 120;

sprintf(Hard.Name[4], "%s", "Epson Stylus C20SX");
sprintf(Hard.Mark[4], "%s", "Drukarka");
Hard.Cost[4] = 320;

static int i = 0;

    ofstream plik; // <------------------------------- ofstream
    try {
          plik.open("c:\\plik.txt", ios::out | ios::app | ios::binary);
        //  plik.seekp(0, ios::end);
          int wielkosc_pliku = plik.tellp();
          Caption = (String)wielkosc_pliku;
          //plik.seekp(i * sizeof(Baza));
          plik.write((char*)&Hard, sizeof(Baza));
    }
    __finally {
          plik.close();
    }
}
//---------------------------------------------------------------------------
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, 18:45

więc jak wyjaśnisz fakt, że ja użyłem klasy ofstream ze wspomnianymi funkcjami kod działa prawidłowo:
Kod: Zaznacz cały
ofstream plik; // <------------------------------- ofstream
    try {
          plik.open("c:\\plik.txt", ios::out | ios::app | ios::binary);
        //  plik.seekp(0, ios::end);
          int wielkosc_pliku = plik.tellp();
          Caption = (String)wielkosc_pliku;
          //plik.seekp(i * sizeof(Baza));
          plik.write((char*)&Hard, sizeof(Baza));
    }

Ano tak to wyjaśnię, że używasz seekp i tellp, czyli wszystko się zgadza :D

Przypomnę o czym mowa, bo widzę, że się nieco pogubiłeś:
Cyfrowy Baron napisał(a):
polymorphism napisał(a):Od kiedy to ostream ma takie metody jak seekg i tellg?


ofstream

Nie wiem od kiedy, ale faktem jest że ma, może są zawarte w bibliotece fstream.h.

Kod, który zamieściłem w poradzie sprawdziłem, użyłem w nim metod które negujesz, a mimo to kompilator nie zwrócił błędu i kod działa prawidłowo.

To, co napisałem o seekg i tellg, odnosiło się do tego, co napisał Miroo_007, czyli:
Kod: Zaznacz cały
ofstream plik;
...
plik.open(sciezka.c_str(), ios::in | ios::binary);
if(plik.good())
{
   plik.seekg(0, ios::end);
   int w = plik.tellg();
   ...
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, 19:17

W nagłówku to one mogą być, bo jest tam klasa fstream, która dziedziczy pośrednio po istream, a ta posiada metody tellg i seekg (-g od get). ofstream, a tej klasy użył Miroo_007, nie posiada takich metod, bo dziedziczy tylko po ostream, która posiada metody tellp i seekp (-p od put).


ofstream, a tej klasy użył Miroo_007, nie posiada takich metod, bo dziedziczy tylko po ostream,


bo dziedziczy tylko po ostream, która posiada metody tellp i seekp (-p od put).


W jednym zdaniu sam przeczysz sobie. Na dobrą sprawę to przestałem rozumieć o czym piszesz, raz piszesz, że posiada innym razem, że ich nie posiada. Konia z rzędem temu, kto to zrozumie... :shock:
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 Miroo_007 » niedziela, 31 maja 2009, 19:25

schemat.JPG

istream:
  • seekg
  • tellg
ostream:
  • seekp
  • tellp
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
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, 20:23

W jednym zdaniu sam przeczysz sobie.

Mylisz się, te trzy cytaty odnoszą się do jednego, prostego stwierdzenia, że ofstream nie posiada metod seekg i tellg. Gdybyś zajrzał do dokumentacji, to nie miałbyś problemów ze zrozumieniem tego, o czym pisze. W drugim cytacie pisząc "takich metod" miałem na myśli metody seekg i tellg - to wynika z pierwszego zdania - więc wystarczyło być nieco uważnym i wszystko byś rozumiał. Zresztą w tym poscie to ty zarzuciłeś mi, że nie mam racji, więc to ty powinieneś udowodnić swoje racje.
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 » poniedziałek, 1 czerwca 2009, 07:39

Jeżeli jedna klasa dziedziczy fukncje po innej klasie, to je zwyczajnie posiada, wiec tutaj jest to o czym ja pisałem, że ofstream posiada te funkcje, gdyż dziedziczy je po fstream, a fstream dziedziczy po ostream - proste...

Mylisz się, te trzy cytaty odnoszą się do jednego, prostego stwierdzenia, że ofstream nie posiada metod seekg i tellg.


Otóż jak najbardziej je posiada, gdyż dziedziczy je po fstream, a fstream dziedziczy je po ostream.
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

Poprzednia stronaNastę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 9 gości