Strona 2 z 4

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

Nowy postNapisane: czwartek, 7 stycznia 2010, 13:04
przez Witold
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.

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

Nowy postNapisane: czwartek, 7 stycznia 2010, 13:12
przez polymorphism

[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-)

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

Nowy postNapisane: czwartek, 7 stycznia 2010, 15:43
przez Cyfrowy Baron
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.

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

Nowy postNapisane: czwartek, 7 stycznia 2010, 16:04
przez polymorphism

[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...

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

Nowy postNapisane: czwartek, 7 stycznia 2010, 17:01
przez Cyfrowy Baron
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 *')


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

Nowy postNapisane: czwartek, 7 stycznia 2010, 18:22
przez polymorphism
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.

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

Nowy postNapisane: czwartek, 7 stycznia 2010, 20:04
przez Cyfrowy Baron
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.

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

Nowy postNapisane: czwartek, 7 stycznia 2010, 20:09
przez Witold
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.

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

Nowy postNapisane: czwartek, 7 stycznia 2010, 20:16
przez Cyfrowy Baron
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.

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

Nowy postNapisane: czwartek, 7 stycznia 2010, 20:39
przez Witold
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.

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

Nowy postNapisane: czwartek, 7 stycznia 2010, 20:43
przez Cyfrowy Baron
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.

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

Nowy postNapisane: piątek, 8 stycznia 2010, 12:01
przez polymorphism
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.

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

Nowy postNapisane: piątek, 8 stycznia 2010, 12:33
przez Witold
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.

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

Nowy postNapisane: piątek, 8 stycznia 2010, 13:07
przez Cyfrowy Baron
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.

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

Nowy postNapisane: piątek, 8 stycznia 2010, 13:47
przez polymorphism
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[]