wartość pola TEdit->Text z pliku binarnego

dział ogólny

wartość pola TEdit->Text z pliku binarnego

Nowy postprzez darasz89 » czwartek, 17 marca 2011, 00:46

witam
mam następujący problem [BCB c++ 6 na windows7 x64]
mam strukturę

Kod: Zaznacz cały
struct Blok
{
int obr;
AnsiString napis;
};


Kod: Zaznacz cały
Blok lista;


wpisuje odpowiednio dane
Kod: Zaznacz cały
lista.obr = obiekt; //obiekt jest typu int
lista.napis = Edit1->Text;


zapisuje później wszystko do pliku
Kod: Zaznacz cały
if ( SaveDialog1->Execute())
  {
        TFileStream *out = new TFileStream(SaveDialog1->FileName, fmCreate);
        out->WriteBuffer(&lista, sizeof(lista));
        out->Free();
        }


później odczytuje
Kod: Zaznacz cały
TFileStream *in;
        if(OpenDialog1->Execute())
        {
        in = new TFileStream(OpenDialog1->FileName, fmOpenRead);
           in->ReadBuffer(&lista, sizeof(lista));
           in->Free();
        }


i przypisuje napis do Edit1->text
Kod: Zaznacz cały
Edit1->Text = "";
Edit1->Text = lista.napis;


i tutaj mam problem:
jeśli wpisze coś do Edit1, zapisze to do pliku i otworze ten plik to w polu Edit1 pojawia się to co zapisałem
lecz jeśli zamknę aplikację [lub uruchomie debugowanie jeszcze raz] to albo pojawiają mi się jakieś losowe znaki, albo same " '''' ", lub mam błąd access violation at address in module Project1.exe read of adress, a przy zakończeniu programu abnormal program termination
z lista.obr jest zawsze wszystko ok [sprawdzam nim warunek w if]
czy robię coś źle? ;) jeśli tak, to proszę o rade
z góry dziękuję za pomoc

EDIT: cały kod
Kod: Zaznacz cały
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

struct Blok
{
int obr;
AnsiString napis;
};

Blok lista;
int obiekt;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
        obiekt = 2;
        lista.obr = obiekt;
        lista.napis = Edit1->Text;
            if ( SaveDialog1->Execute())
            {
            TFileStream *out = new TFileStream(SaveDialog1->FileName, fmCreate);
            out->WriteBuffer(&lista, sizeof(lista));
            out->Free();
            }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
        TFileStream *in;
        if(OpenDialog1->Execute())
        {
        in = new TFileStream(OpenDialog1->FileName, fmOpenRead);
           in->ReadBuffer(&lista, sizeof(lista));
           in->Free();
        }
        Edit1->Text = "";
        if (lista.obr ==2) Label1->Caption = IntToStr(lista.obr);
        Edit1->Text = lista.napis;
}
//---------------------------------------------------------------------------
Nie mniej było pytań, kiedy legły w gruzach konstrukcje sprawiedliwych.
Nie mniej smakowało uleganie szaleństwu, naginanie wieczności.
Avatar użytkownika
darasz89
Bladawiec
Bladawiec
 
Posty: 2
Dołączył(a): czwartek, 17 marca 2011, 00:28
Podziękował : 1
Otrzymał podziękowań: 0
System operacyjny: Windows 7 Pro x64
Kompilator: BCB C++ 6
Gadu Gadu: 0
    Windows 7Firefox

Re: wartość pola TEdit->Text z pliku binarnego

Nowy postprzez Cyfrowy Baron » czwartek, 17 marca 2011, 10:41

darasz89 napisał(a):zapisuje później wszystko do pliku


Jeżeli struktura zawiera zmienną typu AnsiString (String) to taka struktura działa prawidłowo, tylko w uruchomionym programie. Taką strukturę da się zapisać, ale jest problem z odczytaniem, gdyż zmienna AnsiString nie ma określonego rozmiaru. Dla przykładu zmienna typu int zawsze ma długość 32 bitów, gdyż to zmienna 32 bitowa, więc odczytując dane z pliku program czyta dokładnie 32 bity.
W strukturze dane są poukładane w ściśle określony sposób, gdy np. stworzysz taka strukturę:

KOD cpp:     UKRYJ  
struct Blok
{
  int obr;
  char napis[255];
  float value;
};
To podczas odczytywania danych z pliku program najpierw pobierze pierwsze 32 bity i przepisze je do struktury do zmiennej int, potem pobierze 255 bitów gdyż tak został określony rozmiar zmiennej char w strukturze, a potem znów odczyta 32 bity, gdyż float to również zmienna 32 bitowa.
Gdy w miejsce char podstawisz String to nie da się tej zmiennej odczytać, gdyż nie ma ona określonego rozmiaru i program nie wie gdzie ona się kończy. Gdy operacje wykonujesz w uruchomionym programie, to przechowuje on w pamięci długość zapisanej zmiennej i odczytuje ją prawidłowo, ale zamknięciu i ponownym uruchomieniu program nie zna już rozmiaru tej zmiennej.
Musisz stosować zamiast typu String typ char o określonej długości, przy czym musisz określić maksymalną długość tej zmiennej, a wprowadzając dane do tej zmiennej w strukturze nie możesz przekroczyć pojemności zmiennej. Jeżeli dane wprowadzone do zmiennej będą krótsze niż pojemność zmiennej to podczas zapisu do pliku zostaną wprowadzone losowe znaki, ale koniec tekstu zostanie oznaczony i przy wczytywaniu dane zostaną pobrane prawidłowo.

► patrz serwis: Cyfrowy Baron dział: porady -> różne -> Zapisywanie struktur do plików oraz Odczytywanie struktur z plików.

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
darasz89
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
    Windows XPFirefox

Re: wartość pola TEdit->Text z pliku binarnego

Nowy postprzez darasz89 » czwartek, 17 marca 2011, 10:59

Dzięki!! :)
wszystko już działa
pozdrawiam
Nie mniej było pytań, kiedy legły w gruzach konstrukcje sprawiedliwych.
Nie mniej smakowało uleganie szaleństwu, naginanie wieczności.
Avatar użytkownika
darasz89
Bladawiec
Bladawiec
 
Posty: 2
Dołączył(a): czwartek, 17 marca 2011, 00:28
Podziękował : 1
Otrzymał podziękowań: 0
System operacyjny: Windows 7 Pro x64
Kompilator: BCB C++ 6
Gadu Gadu: 0
    Windows 7Firefox

Re: wartość pola TEdit->Text z pliku binarnego

Nowy postprzez polymorphism » czwartek, 17 marca 2011, 11:36

Gdy w miejsce char podstawisz String to nie da się tej zmiennej odczytać, gdyż nie ma ona określonego rozmiaru i program nie wie gdzie ona się kończy. Gdy operacje wykonujesz w uruchomionym programie, to przechowuje on w pamięci długość zapisanej zmiennej i odczytuje ją prawidłowo, ale zamknięciu i ponownym uruchomieniu program nie zna już rozmiaru tej zmiennej.

Tu nie problem w rozmiarze, tylko w tym, że zapisując w ten sposób klasę String, zapisujesz jej bebechy (np. wskaźniki), a nie string, który przechowuje. I wbrew temu, co piszesz, klasa String ma swój rozmiar, tyle tylko, że jest on niezależny od długości tekstu, który w niej siedzi.

Hint: serializacja klas.

To tak, żeby wyprostować pewne nieścisłości.
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
    Windows XPFirefox


  • 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 1 gość

cron