Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

dział ogólny

Re: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez Witold » czwartek, 7 stycznia 2010, 13:04

Cyfrowy Baron napisał(a):Witold trochę mi namieszał.
kinio nie bez powodu użył funkcji SetText(char *) gdyż ta funkcja pobiera wartości typu char, podczas gdy Memo->Text pobiera wartości typu AnsiString (do wersji BCB 2007)
Dlatego też, jeżeli chcemy mieć prawidłowo wyświetlane znaki to należy używać funkcji SetText.


Możesz to jakoś udowodnić ? Jakiś dowód że używając Memo->Text znaki będą nieprawidłowo wyświetlane lub może inne wady tego rozwiązania.
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    NieznanyNieznana

Re: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez polymorphism » czwartek, 7 stycznia 2010, 13:12


[BCC32 Error] Unit1.cpp(149): E2285 Could not find a match for 'ctype<wchar_t>::widen(char *)'


Heh, w moim kodzie chr to pojedynczy char, a ty zapewne podałeś wskaźnik, i tu tkwi błąd. Ta wersja widen nie przyjmuje wskaźnika, tylko pojedynczy znak. To wszystko jest w dokumentacji, chociażby TU.


[BCC32 Error] Unit1.cpp(153): E2342 Type mismatch in parameter 'Text' (wanted 'wchar_t *', got 'wchar_t')


Jak wyżej, tylko w drugą stronę 8-) Text oczekuje wskaźnika, wide-stringa, a wc to pojedynczy wchar_t. Dziwne, że masz z tym problem, bo kompilator jasno wskazał w czym błąd, a w kodzie jasno widać, że chodzi o konwersję pojedynczych znaków.

Nieco bardziej kompletny kod:
KOD cpp:     UKRYJ  
char*   pszBuffer;
wstring wstr;

locale loc(".ACP");// <--- systemowe kodowanie ansi

...

wstr.reserve(iBytesRead); // u mnie daje to niewielki zysk ~100ms/10MB, ale jest dla zasady.

for(unsigned i = 0; i < iBytesRead; ++i)
{
        wchar_t wc = ct.widen(pszBuffer[i]);
        bool ok = ct.is(ctype<wchar_t>::alpha | ctype<wchar_t>::digit | ctype<wchar_t>::punct,wc);
        if(!ok) wc = 0x2588;
        wstr += wc;
}
 

Oczywiście zamiast wstringa można spróbować użyć UnicodeStringa, sam jestem ciekaw, jakie będą różnice w czasach.

a tak wogóle to nie bardzo rozumiem ten twój kod.

E tam, takie typowe C++ 8-)
Ostatnio edytowano czwartek, 7 stycznia 2010, 16:00 przez polymorphism, łącznie edytowano 1 raz
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: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez Cyfrowy Baron » czwartek, 7 stycznia 2010, 15:43

Możesz to jakoś udowodnić ? Jakiś dowód że używając Memo->Text znaki będą nieprawidłowo wyświetlane lub może inne wady tego rozwiązania.


Jak widać na załączonym ekranie:
settext.png


Jak widać SetText jest zapisem bardziej zbliżony do widoku binarnego, aczkolwiek porównałem te zapisy w programie HexEdit i żaden nie jest w pełni zbliżony, ale SetText bardziej.



Odnośnie kodu polymorphism:

wstring.reserve(iBytesRead);

[BCC32 Error] Unit1.cpp(112): E2108 Improper use of typedef 'wstring'



Memo1->Lines->SetText(wstr);

[BCC32 Error] Unit1.cpp(121): E2034 Cannot convert 'wstring' to 'wchar_t *'
[BCC32 Error] Unit1.cpp(121): E2342 Type mismatch in parameter 'Text' (wanted 'wchar_t *', got 'wstring')



Problemem nie jest kod w jakiejkolwiek postaci z tych, które przetestowałem (poza powyższym), lecz klasa TMemo. Jak się okazuje nawet w C++Builder 2007, wczytywanie, a konkretnie przepisywanie danych do Memo zajmuje sporo czasu w zależności od rozmiaru pliku. Edytory hexów nie mają tego problemu, pliki binarne są wczytywane niemal natychmiast.
Przetworzenie pliku we wszystkich kodach, które przetestowałem np. z wykorzystaniem funkcji MyltibyteToWideChar przebiega szybko. Kod jest wstrzymywany dopiero przy wpisywaniu go do Memo. Tak wiec klasa TMemo nie jest chyba najlepszym rozwiązaniem.
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: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez polymorphism » czwartek, 7 stycznia 2010, 16:04


[BCC32 Error] Unit1.cpp(112): E2108 Improper use of typedef 'wstring'


Mój błąd, rozpędziłem się i zamiast wstr napisałem wstring - poprawione.

Memo1->Lines->SetText(wstr);

No to akurat to mogłeś sam poprawić:
Kod: Zaznacz cały
Memo1->Lines->SetText(wstr.c_str());


Edytory hexów nie mają tego problemu, pliki binarne są wczytywane niemal natychmiast.

W hex edytorach nikt nie używa kontrolek typu TMemo, RichEdit itd...
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: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez Cyfrowy Baron » czwartek, 7 stycznia 2010, 17:01

W hex edytorach nikt nie używa kontrolek typu TMemo, RichEdit itd...


Toteż ja o tym właśnie wspomniałem. Temat edytorów nigdy mnie nie interesował, ale przydałaby się jakaś kontrolka do tworzenia takich aplikacji.

No to akurat to mogłeś sam poprawić:

Kod: Zaznacz cały
    Memo1->Lines->SetText(wstr.c_str());




[BCC32 Error] Unit1.cpp(120): E2034 Cannot convert 'const wchar_t *' to 'wchar_t *'
[BCC32 Error] Unit1.cpp(120): E2342 Type mismatch in parameter 'Text' (wanted 'wchar_t *', got 'const wchar_t *')

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: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez polymorphism » czwartek, 7 stycznia 2010, 18:22

Ostatni błąd jest banalny i prosty do poprawienia - żeby było ciekawiej, to nie ja go popełniłem, tylko twórcy VCL-a.
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: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez Cyfrowy Baron » czwartek, 7 stycznia 2010, 20:04

Ja wymyśliłem sobie to tak:

Kod: Zaznacz cały
Memo1->Lines->SetText( const_cast<wchar_t*>( wstr.c_str() ) );


ale wczytanie pliku 2 MB trwa wieczność, właściwie to nawet nie chciało mi się czekać aż skończy wczytywanie.
Do niczego z tym wszystkim. Lepsze efekty uzyskałem korzystając z funkcji MultibyteToWideChar.
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: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez Witold » czwartek, 7 stycznia 2010, 20:09

Cyfrowy Baron napisał(a):Jak widać na załączonym ekranie:


Myślę że to żaden dowód, i nie potwierdza to Twojej teorii "jeżeli chcemy mieć prawidłowo wyświetlane znaki to należy używać funkcji SetText.". Sprawdziłeś jak są łamane linie dla obu metod ? Na ile linii został podzielony tekst w TMemo dla obu metod ? Skoro twierdzisz że jedna jest lepsza, to może wiesz co je różni?

Mały test:
Kod: Zaznacz cały
char * txt = "jeden\r\ndwa\ntrzy\rcztery\n\rpiec";
Memo1->Text = txt;
Memo1->Lines->SetText(txt);


Wydaje mi się że ten test może tłumaczyć dlaczego zawartość TMemo dla obu metod wygląda inaczej.

Dla TMemo jest jeszcze void __fastcall SetTextBuf(char* Buffer); ale
BCB6 help napisał(a):The SetTextBuf method is provided for backwards compatibility only. To set the text of a control now, assign a string value to the Text property.
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    NieznanyNieznana

Re: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez Cyfrowy Baron » czwartek, 7 stycznia 2010, 20:16

Właściwość Text jest typu AnsiString, a SetText pobiera typ char. Przy zapisie do Text gubione są niektóre znaki.
Zapisy się różnią, a ten z SetText jest najbardziej zbliżony do tego co wyświetla mi program HexEditor.
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: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez Witold » czwartek, 7 stycznia 2010, 20:39

Cyfrowy Baron napisał(a):Właściwość Text jest typu AnsiString, a SetText pobiera typ char.

Jaki to ma związek z zawartością TMemo ?

Cyfrowy Baron napisał(a):Przy zapisie do Text gubione są niektóre znaki.

Skąd to wiesz ? Można prosić o jakiś dowód ?

Cyfrowy Baron napisał(a):Zapisy się różnią, a ten z SetText jest najbardziej zbliżony do tego co wyświetla mi program HexEditor.

Ten edytor Hex łamie linie na znakach o kodach 10 , 13 czy sekwencji 13, 10?
Żeby to porównywać trzeba by mieć te same długości linii, mylę się ? Na Screenie nie widać końca linii. Linia może mieć z 1000 znaków , może więcej.
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    NieznanyNieznana

Re: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez Cyfrowy Baron » czwartek, 7 stycznia 2010, 20:43

Nie chce mi się już tego w kółko wałkować. Nie to jest problemem lecz, że Memo oczekuje wartości typu wchar_t dla SetText i UnicodeString dla Text. Przepisywanie zawartości pliku do Memo trwa w przypadku 2MB około 1 min i to jest głównym problemem. Skup się na tym.
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: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez polymorphism » piątek, 8 stycznia 2010, 12:01

Cyfrowy Baron napisał(a):Do niczego z tym wszystkim. Lepsze efekty uzyskałem korzystając z funkcji MultibyteToWideChar.

Podejrzewam, że nieznacznie lepsze, wszak zasadniczym problemem jest powolność TMemo, które nie jest przystosowane do parsowania tak dużych ilości danych.



Jeszcze wrócę do wcześniejszego posta:
[...] przydałaby się jakaś kontrolka do tworzenia takich aplikacji.

W sumie jest: TWinControl.
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: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez Witold » piątek, 8 stycznia 2010, 12:33

polymorphism napisał(a):Oczywiście zamiast wstringa można spróbować użyć UnicodeStringa, sam jestem ciekaw, jakie będą różnice w czasach.


dla pliku 7mb, proc c2d 2,4ghz, wyszło mi:
std::wstring - 875ms z wstring.reserve(iBytesRead);
UnicodeString dla wstr += wc; - 1687ms
UnicodeString dla wstr.SetLength(iBytesRead); dalej wstr[i+1] = wc; zamiast wstr += wc; - 670ms

Cyfrowy Baron napisał(a):Nie chce mi się już tego w kółko wałkować.

Zrobiłem następny test:po zastąpieniu znaków 0, 10, 13 przez spacje dla pliku który zawierał znaki o kodach 0-255 zawartość w Memo1 (przepisanie przez Text) i Memo2 (przepisanie przez Lines->SetText) była identyczna. Metoda "Text" nie gubi znaków, nie wiem czemu tak napisałeś.

Cyfrowy Baron napisał(a):Nie to jest problemem lecz, że Memo oczekuje wartości typu wchar_t dla SetText i UnicodeString dla Text. Przepisywanie zawartości pliku do Memo trwa w przypadku 2MB około 1 min i to jest głównym problemem.


test1, 7mb plik mp3, ustawienia Memo1->WordWrap na false, ScrollBars = ssBoth ,metoda "Text", czas wykonywania ~2.4s, proc c2d 2,4ghz.
test2, 7mb plik mp3, ustawienia Memo1->WordWrap na true, ScrollBars = ssNone ,metoda "Text", czas wykonywania ~48s, proc c2d 2,4ghz.
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    NieznanyNieznana

Re: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez Cyfrowy Baron » piątek, 8 stycznia 2010, 13:07

Nie wiem skąd tobie te czasy tak powychodziły. U mnie nie ma znaczenia jak jest ustawiony WordWrap, wczytywanie w C++Builder 2010 trwa wieki.

Pokaż jak przerobiłeś ten kod w całości, bo coś się tutaj nie zgadza.
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: Wczytywanie plików binarnych do obiektu Memo - wg. pomysłu k

Nowy postprzez polymorphism » piątek, 8 stycznia 2010, 13:47

std::wstring - 875ms z wstring.reserve(iBytesRead);
UnicodeString dla wstr += wc; - 1687ms
UnicodeString dla wstr.SetLength(iBytesRead); dalej wstr[i+1] = wc; zamiast wstr += wc; - 670ms

Czyli wstring jest prawie 2x szybszy od VCL-owej wersji stringa. Wersja z SetLength jest wyraźnie szybsza, ale ciekawe jakby ona wyglądała w zestawieniu z analogicznym kodem, z użyciem wstringa:
Kod: Zaznacz cały
wstr.resize(iBytesRead);
...
wstr[i] = wc;

U mnie czasy w wersji release wyglądają tak (dla 10MB):
   1375ms - bez reserve, op+=
   1282ms - reserve, op+=
   1203ms - resize, op[]
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

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 27 gości

cron