|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 15.11.2008, 16:21 Titel: Unicode + wfstream + winapi |
|
|
Hat jemand schon mal erfolgreich mit diesen Dingen gleichzeitig gearbeitet?
Es gibt da leider ziemlich bescheuerte Probleme.
So ließt wfstream wie ein normaler fstream nur ein Byte pro Zeichen. Das hier hab ich auch schon probiert, da wird allerdings gar nichts mehr ausgelesen.
Außerdem klappt die Darstellung eines Unicodezeichens nicht auf allen winapi-Elementen.
In Menüs und Tabcontrols klappt es, auf Buttons und statischem Text erscheinen dort nur Rechtecke.
Gibt es dafür Lösungen?
Ich kann mir kaum vorstellen, wofür man überhaupt Unicode verwenden soll, wenn weder Input noch Output damit funktioniert... _________________ www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console
Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet... |
|
Nach oben |
|
|
fast hawk Senior JLI'ler
Anmeldedatum: 15.07.2005 Beiträge: 237 Wohnort: Freiburg Medaillen: Keine
|
Verfasst am: 15.11.2008, 17:20 Titel: |
|
|
mmmhh also mit TEXT und so hab ich noch nie gearbeitet aber ich benutz file streams und unicode gleichzeitig + winapi.
Bei der Winapi gibts bis auf ein paar wenige Ausnahmen zu jeder Funktion eine W Variante die je nachdem wie du deinen Kompiler eingestellt hast standerdmäßig benutzt wird.
und zu den fstream
::std::basic_ifstream<wchar_t> Input
und
::std::basic_ofstream<wchar_t> Output
geht eigtl problemlos ...
wenn du willst kann ich mal meine Read und Write Funktionen posten sind kein so großes geheimnis^^
bzw zu deinem Problem mit dem Zeichensatz welchen Kompiler benutzt du?
Ich hatte sowohl mit VC++ 2005 Express und auch mit dem 2008 keine Probleme _________________ Jetziges Projekt: The Ring War
Status: 40%
-----------------------------------
Nicht weil es schwer ist, wagen wir es nicht, sondern weil wir es nicht wagen, ist es schwer.
--
Lucius Annaeus Seneca (4)
röm. Philosoph, Dramatiker und Staatsmann |
|
Nach oben |
|
|
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 15.11.2008, 19:01 Titel: |
|
|
fast hawk hat Folgendes geschrieben: | Bei der Winapi gibts bis auf ein paar wenige Ausnahmen zu jeder Funktion eine W Variante die je nachdem wie du deinen Kompiler eingestellt hast standerdmäßig benutzt wird. |
Nuja...ich hab bei den Projekteinstellungen schon auf Unicode umgeschaltet und der Compiler schlägt von den verwendeten Funktionen auch entsprechend die W-Version vor. Trotzdem werden Zeichen außerhalb des ASCII-Satzes nur in Menüs und in Tabs dargestellt.
Als Beispiel hab ich mal dieses kyrillische Zeichen genommen: Д.
Kannst du das beispielsweise als statischen Text anzeigen lassen?
fast hawk hat Folgendes geschrieben: | wenn du willst kann ich mal meine Read und Write Funktionen posten sind kein so großes geheimnis^^ |
Ja, zeig mal bitte. Ich hab durch die Methode das Д nicht korrekt auslesen können.
Ich verwende VisualStudio 2005. _________________ www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console
Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet... |
|
Nach oben |
|
|
fast hawk Senior JLI'ler
Anmeldedatum: 15.07.2005 Beiträge: 237 Wohnort: Freiburg Medaillen: Keine
|
Verfasst am: 19.11.2008, 20:27 Titel: |
|
|
Code: |
typedef bool lcgb;
typedef wchar_t lcgcw;
typedef ::std::basic_string<lcgcw> lcgsw;
|
Code: |
std::vector<lcgsw > ReadFile(lcgsw FileName,lcgsw Spliter) //Lisst eine Datei aus
{
lcgsw buffer; // Buffer bereitstellen
std::basic_ifstream<lcgcw> input (FileName.c_str()); // Datei einlesen
if (!input)
{
std::vector<lcgsw > Error;
return Error;
}
std::vector<lcgsw > Ausgabe;
// Solane eine Zeile einlesen bis keine mehr da ist.
while(std::getline(input, buffer))
{
// Wenn die Zeile leer ist überspringen
if (buffer.empty ())
continue;
// Zeile Splitten nach 'Splitter'
std::vector<lcgsw > split_string (splitString(buffer, Spliter));
for(unsigned long i=0;i < split_string.size();i++)
{
Ausgabe.push_back(split_string[i].c_str());
}
}
return Ausgabe;
}
|
Code: |
lcgb WriteFile(lcgsw Text,lcgsw FileName)
{
std::basic_ofstream<wchar_t> out (FileName.c_str());
out << Text.c_str() << std::endl;
return true;
}
|
das sind die beiden Funktionen ich glaub zum größteil auch iwo geklaut und zusammengestückelt....
sry das ich so lang zum antworten gebraucht hab
also test nr.1 war erfolgreich:
statisch als Text kann meiner(VC 2008) sie anzeigen jedoch muss er dafür die quellcode dateien (.cpp/.rc) in ein unicode format konvertieren.
vllt macht das der VC 2005 noch nicht.
test nr. 2
mmmhhh also alles programm interne geht unicode nur:
die streams können keine unicode textdateien lesen.....
hab grad vorhin auch mal gegoogelt so wirklich findet man nichts außer des irgendjmd von uifstream etc. schreibt aber des hab ich in meiner biblotheck nicht gefunden. ich werd mal gucken das interessiert mich jetzt um ehrlich zu sein auch...
viele grüße _________________ Jetziges Projekt: The Ring War
Status: 40%
-----------------------------------
Nicht weil es schwer ist, wagen wir es nicht, sondern weil wir es nicht wagen, ist es schwer.
--
Lucius Annaeus Seneca (4)
röm. Philosoph, Dramatiker und Staatsmann |
|
Nach oben |
|
|
fast hawk Senior JLI'ler
Anmeldedatum: 15.07.2005 Beiträge: 237 Wohnort: Freiburg Medaillen: Keine
|
Verfasst am: 19.11.2008, 20:50 Titel: |
|
|
also ich hab ne naja bisschen geschummelte Möglichkeit gefunden
Unicode auszulesen. geht sicher noch feiner....
Code: |
char cbuffer[512];
wchar_t wbuffer[256];
lcgsw buffer; // Buffer bereitstellen
::std::ifstream input (L"d:\\text.txt",::std::ios::in | ::std::ios::binary); // Datei einlesen
if (!input.is_open())
{
std::vector<lcgsw > Error;
return Error;
}
ZeroMemory(cbuffer,512);
input.read(cbuffer,512);
::memcpy(wbuffer,&cbuffer[2],510);
buffer = wbuffer;
Ausgabe.push_back(buffer); |
_________________ Jetziges Projekt: The Ring War
Status: 40%
-----------------------------------
Nicht weil es schwer ist, wagen wir es nicht, sondern weil wir es nicht wagen, ist es schwer.
--
Lucius Annaeus Seneca (4)
röm. Philosoph, Dramatiker und Staatsmann |
|
Nach oben |
|
|
fast hawk Senior JLI'ler
Anmeldedatum: 15.07.2005 Beiträge: 237 Wohnort: Freiburg Medaillen: Keine
|
Verfasst am: 19.11.2008, 21:18 Titel: |
|
|
nachtrag:
Code: |
std::vector<lcgsw > ReadFile(lcgsw FileName,lcgsw Spliter) //Lisst eine Datei aus
{
char* cbuffer;
wchar_t* wbuffer;
unsigned long count = 0;
lcgsw buffer; // Buffer bereitstellen
::std::ifstream input (FileName.c_str(),::std::ios::in | ::std::ios::binary); // Datei einlesen
if (!input.is_open())
{
std::vector<lcgsw > Error;
return Error;
}
std::vector<lcgsw > Ausgabe;
{
input.seekg(0,::std::ios::end);
count = input.tellg();count+=2;
input.seekg(0);
cbuffer = new char[count];
wbuffer = new wchar_t[count/2-2];
ZeroMemory(cbuffer,count);
input.get(cbuffer,count);
::memcpy(wbuffer,&cbuffer[2],count-2);
buffer = wbuffer;
std::vector<lcgsw > split_string (splitString(buffer, Spliter));
for(unsigned long i=0;i < split_string.size();i++)
{
Ausgabe.push_back(split_string[i].c_str());
}
}
return Ausgabe;
}
|
_________________ Jetziges Projekt: The Ring War
Status: 40%
-----------------------------------
Nicht weil es schwer ist, wagen wir es nicht, sondern weil wir es nicht wagen, ist es schwer.
--
Lucius Annaeus Seneca (4)
röm. Philosoph, Dramatiker und Staatsmann |
|
Nach oben |
|
|
fast hawk Senior JLI'ler
Anmeldedatum: 15.07.2005 Beiträge: 237 Wohnort: Freiburg Medaillen: Keine
|
Verfasst am: 20.11.2008, 15:28 Titel: |
|
|
ich glaub das ist jetzt erstmal mein letzter eintrag:
CPP: | #ifdef UNICODE
#define ReadTextFile ReadTextFileW
#else
#define ReadTextFile ReadTextFileA
#endif |
CPP: | template<typename IC>
::std::basic_string<char> ReadTextFileA(::std::basic_string<IC> FileName)
{
::std::ifstream iStream (FileName.c_str(),::std::ios::in | ::std::ios::binary | ::std::ios::ate); // Datei einlesen
if (!iStream.is_open()) { return ""; }
unsigned long FileSize = 1+iStream.tellg(); iStream.seekg(0);
char* tBuff = new char[FileSize]; ZeroMemory(tBuff,FileSize);
wchar_t* wtBuff = 0;
::std::basic_string<char> result;
iStream.read(tBuff,FileSize);
if(tBuff[0] == (char)0xEF && tBuff[1] == (char)0xBB && tBuff[2] == (char)0xBF) { //UTF - 8
result = &tBuff[3];
delete[] tBuff;
return result;
}
else if(tBuff[0] == (char)0xFF && tBuff[1] == (char)0xFE) { //UTF - 16 little endian
wtBuff = new wchar_t[((FileSize-1)/sizeof(wchar_t))];
::memcpy(wtBuff,&tBuff[2],FileSize-3);
wtBuff[((FileSize-1)/sizeof(wchar_t))-1] = '\0';
::WideCharToMultiByte(CP_ACP,0,wtBuff,((FileSize-2)/sizeof(wchar_t)),tBuff,FileSize,0,0);
result = tBuff;
delete[] wtBuff;
delete[] tBuff;
return result;
}
else if(tBuff[0] == (char)0xFE && tBuff[1] == (char)0xFF) { //UTF - 16 big endian
char tcBuffer = 0;
for(unsigned int cChars=2;cChars<(FileSize-1);cChars+=2) {
tcBuffer = tBuff[cChars];
tBuff[cChars] = tBuff[cChars+1];
tBuff[cChars+1] = tcBuffer; }
wtBuff = new wchar_t[((FileSize-1)/sizeof(wchar_t))];
::memcpy(wtBuff,&tBuff[2],FileSize-3);
wtBuff[((FileSize-1)/sizeof(wchar_t))-1] = '\0';
::WideCharToMultiByte(CP_ACP,0,wtBuff,((FileSize-2)/sizeof(wchar_t)),tBuff,FileSize,0,0);
result = tBuff;
delete[] wtBuff;
delete[] tBuff;
return result;
}
else if(tBuff[0] == (char)0xFF && tBuff[0] == (char)0xFE && tBuff[2] == (char)0x00 && tBuff[3] == (char)0x00)return "not supported file typ(UTF-32LE)"; //UTF - 32 little endian
else if(tBuff[0] == (char)0x00 && tBuff[1] == (char)0x00 && tBuff[2] == (char)0xFE && tBuff[3] == (char)0xFF)return "not supported file typ(UTF-32BE)"; //UTF - 32 big endian
else { //ASCII
result = tBuff;
delete[] tBuff;
return result;
}
return "";
}
template<typename IC>
::std::basic_string<wchar_t> ReadTextFileW(::std::basic_string<IC> FileName)
{
::std::ifstream iStream (FileName.c_str(),::std::ios::in | ::std::ios::binary | ::std::ios::ate); // Datei einlesen
if (!iStream.is_open()) { return L""; }
unsigned long FileSize = 1+iStream.tellg(); iStream.seekg(0);
char* tBuff = new char[FileSize]; ZeroMemory(tBuff,FileSize);
wchar_t* wtBuff = 0;
::std::basic_string<wchar_t> result;
iStream.read(tBuff,FileSize);
if(tBuff[0] == (char)0xEF && tBuff[1] == (char)0xBB && tBuff[2] == (char)0xBF) { //UTF - 8
wtBuff = new wchar_t[FileSize-3];
::MultiByteToWideChar(CP_ACP,0,&tBuff[3],(FileSize-3),wtBuff,(FileSize-3));
result = wtBuff;
delete[] wtBuff;
delete[] tBuff;
return result;
}
else if(tBuff[0] == (char)0xFF && tBuff[1] == (char)0xFE) { //UTF - 16 little endian
wtBuff = new wchar_t[((FileSize-1)/sizeof(wchar_t))];
::memcpy(wtBuff,&tBuff[2],FileSize-3);
wtBuff[((FileSize-1)/sizeof(wchar_t))-1] = '\0';
result = wtBuff;
delete[] wtBuff;
delete[] tBuff;
return result;
}
else if(tBuff[0] == (char)0xFE && tBuff[1] == (char)0xFF) { //UTF - 16 big endian
char tcBuffer = 0;
for(unsigned int cChars=2;cChars<(FileSize-1);cChars+=2) {
tcBuffer = tBuff[cChars];
tBuff[cChars] = tBuff[cChars+1];
tBuff[cChars+1] = tcBuffer; }
wtBuff = new wchar_t[((FileSize-1)/sizeof(wchar_t))];
::memcpy(wtBuff,&tBuff[2],FileSize-3);
wtBuff[((FileSize-1)/sizeof(wchar_t))-1] = '\0';
result = wtBuff;
delete[] wtBuff;
delete[] tBuff;
return result;
}
else if(tBuff[0] == (char)0xFF && tBuff[0] == (char)0xFE && tBuff[2] == (char)0x00 && tBuff[3] == (char)0x00)return L"not supported file typ(UTF-32LE)"; //UTF - 32 little endian
else if(tBuff[0] == (char)0x00 && tBuff[1] == (char)0x00 && tBuff[2] == (char)0xFE && tBuff[3] == (char)0xFF)return L"not supported file typ(UTF-32BE)"; //UTF - 32 big endian
else { //ASCII
wtBuff = new wchar_t[FileSize];
::MultiByteToWideChar(CP_ACP,0,tBuff,FileSize,wtBuff,FileSize);
result = wtBuff;
delete[] wtBuff;
delete[] tBuff;
return result;
}
return L"";
} |
zwei Funktionen die den Text aus jedem Format das Notepad erstellen kann ausliehst. einmal mit einem char Rückgabewert und einmal mit einem wchar_t Rückgabewert. UTF-32 eigtl. imo noch nicht unterstüzt es gibt auch noch keinen wchar_t mit 4 bytes (soweit ich weiß)
Rückmeldung ist erwünscht *g*
Test:
Zitat: |
Ausgabe in Unicode(2Bytes)
Dateigröße: 6,772 Bytes
3.0 GHz(2x) bei 7200u/m
1mil(UTF-16BE):97.83 Sek
1mil(ANSII):81.15 Sek
1mil(UTF-16LE):77.47 Sek
1mil(UTF-:78.39 Sek
|
viele grüße
Lukas _________________ Jetziges Projekt: The Ring War
Status: 40%
-----------------------------------
Nicht weil es schwer ist, wagen wir es nicht, sondern weil wir es nicht wagen, ist es schwer.
--
Lucius Annaeus Seneca (4)
röm. Philosoph, Dramatiker und Staatsmann
Zuletzt bearbeitet von fast hawk am 20.11.2008, 18:34, insgesamt einmal bearbeitet |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 20.11.2008, 17:53 Titel: |
|
|
fast hawk: versuch ma bitte die edit- und die c++-funktionen zu benutzen, sich so dadurchzulesen tut ein bisschen in den Augen weh also cpp statt code-tag.
TLOP: wieso funktioniert die Methode mit dem codecvt-objekt nicht? das ist meiner meinung nach die effektivste (und auch dafür entwickelte) Methode, vor allem weil du in der STL bleibst und nichts zusammenmischst. Poste am besten mal deine Implementierung (also den Code) wie du std::codecvt benutzt, besser mehr als wenig =)
Gruß DXer |
|
Nach oben |
|
|
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 20.11.2008, 19:14 Titel: |
|
|
Cool, danke für deine Mühe
Ich teste es.
fast hawk hat Folgendes geschrieben: | also test nr.1 war erfolgreich:
statisch als Text kann meiner(VC 2008) sie anzeigen jedoch muss er dafür die quellcode dateien (.cpp/.rc) in ein unicode format konvertieren.
vllt macht das der VC 2005 noch nicht. |
Wenn ich ein exotisches Zeichen im Quellcode ablege, fragt VS2005 das auch und wandelt die Quellcodedatei in Unicode um. Hab das gleiche mit der RC-Datei gemacht, aber es gibt keine Besserung.
Hast du alle Quellcodedateien umwandeln müssen? Hat VS das automatisch gemacht oder gibts da ne Option?
@DirectXer:
Hab noch mal kontrolliert.
Hatte die Datei nicht im binären Modus geöffnet. Auslesen funktioniert nun =)
Kleiner Schönheitsfehler ist, dass man getline nicht mehr anständig verwenden kann, da der Zeilenumbruch nicht nur von einem Zeichen(\n), sondern zwei dargestellt wird(\r\n). Muss also das eine Zeichen nach std::getline() noch abtrennen und auch das erste Zeichen, das er überhaupt liest.
Darstellung auf winapi-Controls ist nun immer noch das Problem. _________________ www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console
Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet... |
|
Nach oben |
|
|
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 29.11.2008, 15:57 Titel: |
|
|
Also, es liegt am Font.
Beim Ressourceneditor in VS war MS Sans Serif eingestellt, was diese Zeichen offenbar gar nicht kennt. Tahoma beispielsweise funktioniert.
Was mich noch interessiert, fast hawk, welchen Font hattest du eingestellt und auf welchem Betriebssystem hast du es getestet? _________________ www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console
Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet... |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group Deutsche Übersetzung von phpBB.de
|