Discussion:
Polnische Strings unter deutscher Benutzerumgebung
(zu alt für eine Antwort)
Björn Dehmel
2004-10-18 09:29:03 UTC
Permalink
Hallo noch mal.

Wir haben in unserer Datenbank (AS400) Strings in polnischer Sprache
gespeichert, die ich gerne korrekt auf dem PC (Windows XP deutsch) anzeigen
lassen möchte. Wie macht man das?

Gruß Björn
Jochen Kalmbach
2004-10-18 09:37:13 UTC
Permalink
Post by Björn Dehmel
Hallo noch mal.
Wir haben in unserer Datenbank (AS400) Strings in polnischer Sprache
gespeichert, die ich gerne korrekt auf dem PC (Windows XP deutsch)
anzeigen lassen möchte. Wie macht man das?
1. Du musst rausfinden in welcher Kodierung die Strings vorliegen (also in
welcher Codepage)

2. Dann wandle den eingabestring z.B: via "MultiByteToWideChar" nach
UNICODE um

3. Zeige die Strings dann an
--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Jochen Kalmbach
2004-10-18 10:04:53 UTC
Permalink
Post by Jochen Kalmbach
1. Du musst rausfinden in welcher Kodierung die Strings vorliegen
(also in welcher Codepage)
Hier gibt es die CP-Identifiers von Windows:
http://msdn.microsoft.com/library/en-us/intl/unicode_81rn.asp
--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Jens Geyer
2004-10-18 10:48:51 UTC
Permalink
Hallo *,
Post by Jochen Kalmbach
Post by Björn Dehmel
Wir haben in unserer Datenbank (AS400) Strings in polnischer Sprache
gespeichert, die ich gerne korrekt auf dem PC (Windows XP deutsch)
anzeigen lassen möchte. Wie macht man das?
1. Du musst rausfinden in welcher Kodierung die Strings vorliegen
(also in welcher Codepage)
ACK. Polnisch verwendet üblicherweise die Windows-1250
Post by Jochen Kalmbach
2. Dann wandle den eingabestring z.B: via "MultiByteToWideChar"
nach UNICODE um
Oder erzeuge alternative einen Font mit dem passenden Charset, für Polnisch
wäre das das EASTEUROPE_CHARSET.
Post by Jochen Kalmbach
3. Zeige die Strings dann an
Für Unicode kannst Du ohne weitere Maßnahmen TexOut32W auf
nicht-NT-Plattformen wie 95/98/ME verwenden.

Für die Ausgabe als normaler (lies: nicht Unicode) String mit dem genannten
Font kannst Du hingegen alle verfügbaren Funktionen verwendn, handelst Dir
damit aber wieder andere Probleme ein.

Viele Wege führen in's ROM, jetzt mußt Du nur noch den für deinen
Anwendungsfall am besten geeigneten finden.
JensG
Jochen Kalmbach
2004-10-18 11:02:31 UTC
Permalink
Hallo Jens,
Post by Jens Geyer
Post by Jochen Kalmbach
1. Du musst rausfinden in welcher Kodierung die Strings vorliegen
(also in welcher Codepage)
ACK. Polnisch verwendet üblicherweise die Windows-1250
Man beachte aber, dass auf einer AS400 die Codierung i.d.R. in EBCDIC
erfolgt...

Aber was dass nun als windows CP sein soll, bin ich leider überfragt (da
gibt es ca. 34 EBCDIC Codepages)
--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Björn Dehmel
2004-10-18 11:19:02 UTC
Permalink
Post by Jochen Kalmbach
Post by Jens Geyer
Post by Jochen Kalmbach
1. Du musst rausfinden in welcher Kodierung die Strings vorliegen
(also in welcher Codepage)
ACK. Polnisch verwendet üblicherweise die Windows-1250
Man beachte aber, dass auf einer AS400 die Codierung i.d.R. in EBCDIC
erfolgt...
Aber was dass nun als windows CP sein soll, bin ich leider überfragt (da
gibt es ca. 34 EBCDIC Codepages)
Genau das scheint das Problem zu sein. Selbst in der deutschen
AS400-Emulation werden die polnischen Zeichen nicht richtig dargestellt und
mit Fragezeichen ersetzt. Selbst wenn ich die Codepage der Emulation 1141
(Deutschland Euro) auf 1153 (Polnisch Euro) ändere, sehe ich nicht die
richtigen Zeichen.

Eingegeben wird der Text in Polen. Die Rechner dort sich natürlich auch
komplett auf polnisch installiert.
Carsten Witte [MVP]
2004-10-18 12:04:39 UTC
Permalink
Björn Dehmel wrote in
Post by Björn Dehmel
Post by Jochen Kalmbach
Post by Jens Geyer
Post by Jochen Kalmbach
1. Du musst rausfinden in welcher Kodierung die Strings vorliegen
(also in welcher Codepage)
ACK. Polnisch verwendet üblicherweise die Windows-1250
Man beachte aber, dass auf einer AS400 die Codierung i.d.R. in EBCDIC
erfolgt...
Aber was dass nun als windows CP sein soll, bin ich leider überfragt (da
gibt es ca. 34 EBCDIC Codepages)
Genau das scheint das Problem zu sein. Selbst in der deutschen
AS400-Emulation werden die polnischen Zeichen nicht richtig dargestellt und
mit Fragezeichen ersetzt. Selbst wenn ich die Codepage der Emulation 1141
(Deutschland Euro) auf 1153 (Polnisch Euro) ändere, sehe ich nicht die
richtigen Zeichen.
Wenn die Zeichen auf der AS400 "nativ" vorliegen, sind die doch bestimmt
mit EBCDIC codiert, oder?

Carsten Witte [MVP]
--
mpdvc-FAQ: http://www.mpdvc.de
Newssuche: http://groups.google.com/advanced_group_search
Private : http://www.carsti.de/dmfc.html

Ich beantworte keine Fragen, die per e-mail eingehen!
Björn Dehmel
2004-10-18 12:15:04 UTC
Permalink
Post by Carsten Witte [MVP]
Wenn die Zeichen auf der AS400 "nativ" vorliegen, sind die doch bestimmt
mit EBCDIC codiert, oder?
Carsten Witte [MVP]
Sie sind EBCDIC gespeichert, das ist richtig.
Jochen Kalmbach
2004-10-18 12:31:47 UTC
Permalink
Post by Björn Dehmel
Post by Carsten Witte [MVP]
Wenn die Zeichen auf der AS400 "nativ" vorliegen, sind die doch
bestimmt mit EBCDIC codiert, oder?
Carsten Witte [MVP]
Sie sind EBCDIC gespeichert, das ist richtig.
Nehme einfach das folgende Beispiel und füge in "inputString" Deine
Eingangsdaten ein und betrachte die Ausgabe und das passende nimmst Du
dann (natürlichz nur wenn genau eines passend ist!)

Falls nichts passendes dabei sein sollte, musst Du noch die notwendigen
Codepages nachinstallieren!


<code>
#include <windows.h>
#include <stdio.h>

const char *inputString = NULL;

BOOL CALLBACK MyEnumCodePagesProc(
LPTSTR lpCodePageString // code page identifier string
)
{
_tprintf(_T("%8.8s: "), lpCodePageString);

if (inputString != NULL)
{
// convert input with this codepage and output the unicode string:
long cp = _tcstoul(lpCodePageString, NULL, 10);
if (cp > 0)
{
int size = MultiByteToWideChar(cp, 0, inputString, -1, NULL, 0);
if (size > 0)
{
wchar_t *wc = new wchar_t[size+1];
MultiByteToWideChar(cp, 0, inputString, -1, wc, size+1);
wprintf(wc);
delete [] wc;
}
else
{
_tprintf(_T("Error converting string... 0x%8.8x"),
GetLastError());
}
}
}
_tprintf(_T("\n"));

return TRUE;
}


int _tmain(int argc, _TCHAR* argv[])
{

inputString = "Hello world";
EnumSystemCodePages(MyEnumCodePagesProc, CP_INSTALLED);

return 0;
}
</code>
--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Jochen Kalmbach
2004-10-18 12:55:40 UTC
Permalink
Ups... natürlich über den unicode-bug in der CRT gestolpert:

Ersetze bitte:
wprintf(wc);
durch:
DWORD dwWritten;
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wc,
size, &dwWritten, NULL);

Die CRT kann leider kein Unicode auf der console ausgeben... (schnief).


Falls es ganz komische Zeichen sind, musst Du auch noch darauf achten, dass
die Console Unicode kann (also Lucidia Schriftart verwenden).
--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Andreas Heyer
2004-10-18 13:56:06 UTC
Permalink
Hallo Jochen!
???
Post by Jochen Kalmbach
Die CRT kann leider kein Unicode auf der console ausgeben...
(schnief).
wcout kommt doch mit L"Das ist mein Text" prima zurecht!?
Post by Jochen Kalmbach
Falls es ganz komische Zeichen sind, musst Du auch noch darauf
achten, dass
die Console Unicode kann (also Lucidia Schriftart verwenden).
Die Konsole kann UNICODE, die CRT nicht? Komischerweise will ein
managed C#-Konsolen-Programm auch kein Eurozeichen auf der Konsole
drucken...

MfG
Andreas
Jochen Kalmbach
2004-10-18 14:35:18 UTC
Permalink
Hallo Andreas,
Post by Andreas Heyer
???
Bug Details: wprintf has no UNICODE support
http://lab.msdn.microsoft.com/ProductFeedback/viewfeedback.aspx?
feedbackid=fac6050a-d359-4eb6-a448-1280ba10151b
Post by Andreas Heyer
Post by Jochen Kalmbach
Die CRT kann leider kein Unicode auf der console ausgeben...
(schnief).
wcout kommt doch mit L"Das ist mein Text" prima zurecht!?
Ich hab ja auch nicht gesagt, das sie nicht mit wchar_t zurechtkommt....

Hast Du schon mal versucht Zeichen > 127 auszugeben?
(meine Behauptung bezieht sich im übrigen auf wprintf; vermutlich trifft es
aber auch auf wcout zu).
Post by Andreas Heyer
Post by Jochen Kalmbach
Falls es ganz komische Zeichen sind, musst Du auch noch darauf achten, dass
die Console Unicode kann (also Lucidia Schriftart verwenden).
Die Konsole kann UNICODE, die CRT nicht? Komischerweise will ein
managed C#-Konsolen-Programm auch kein Eurozeichen auf der Konsole
drucken...
Das liegt an dem komischen verhalten, dass die standard-schriftart der
Console kein Unicode darstellen kann!

Stell doch mal die Schriftart auf "Lucida Console" um und -schwups-- wird
bei der Ausgabe das Eur-Zeichen dargestellt...
--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Andreas Heyer
2004-10-19 05:23:45 UTC
Permalink
Hallo Jochen,
Post by Jochen Kalmbach
Post by Andreas Heyer
wcout kommt doch mit L"Das ist mein Text" prima zurecht!?
Ich hab ja auch nicht gesagt, das sie nicht mit wchar_t
zurechtkommt....
???
Womit stellt man denn UNICODE dar? Das ist doch absoluter Schwachsinn,
wenn die Konsole auch mit wchar_t nur die ersten 255 ANSI-Zeichen kann.
Sollen sie halt einen UNICODE-Font nehmen. Manchmal versteht man MS
wirklich nicht...
Post by Jochen Kalmbach
Hast Du schon mal versucht Zeichen > 127 auszugeben?
(meine Behauptung bezieht sich im übrigen auf wprintf; vermutlich trifft es
aber auch auf wcout zu).
Stell doch mal die Schriftart auf "Lucida Console" um und -schwups-- wird
bei der Ausgabe das Eur-Zeichen dargestellt...
Lucida ändert nichts! Gibt nichts über Code 255! Absoluter Mumpitz.

Habe damit getestet:

#include <iostream>

using namespace std;

int main(int argc,char argv[])
{
//wcout<<L"UNICODE: ÄÖÜäöü@€"<<endl;
for(int i=128;i<260;i++)
wcout<<L"Code: "<<i<<L"\tUNI-Zeichen:
"<<(wchar_t)i<<L"\tANSI-Zeichen:"<<char)i<<endl;

return 0;
}

Wenn die erste Zeile nicht auskommentiert wird, kommt man gar nicht bis
zur Schleife. Und die Schleife bricht nach 255 ab.
Aber per Tastatur sind ÄÖÜäöü@€ eingebar!???

MfG
Andreas
Jochen Kalmbach
2004-10-19 05:50:12 UTC
Permalink
Hallo Andreas,
Post by Andreas Heyer
Post by Jochen Kalmbach
Ich hab ja auch nicht gesagt, das sie nicht mit wchar_t
zurechtkommt....
???
Womit stellt man denn UNICODE dar? Das ist doch absoluter Schwachsinn,
wenn die Konsole auch mit wchar_t nur die ersten 255 ANSI-Zeichen kann.
Ich hab auch nicht gesagt, dass die Console nur die ersten 255 Zeichen
darstellen kann!
Die Console kann (min.) alle Latin-Zeichen darstellen.
Aber z.B. Chinesische Zeichen per Default eben nicht! Dazu benötigt man
dann eine andere Schriftart (Lucida Console) und man muss natürlich die
chinesische Fonts auf senem Rechner installiert haben!
Post by Andreas Heyer
Sollen sie halt einen UNICODE-Font nehmen. Manchmal versteht man MS
wirklich nicht...
Warum per default nicht schon der "korrekte" Font verwendet wird ist mir
allerdings auch rätselhaft...
Post by Andreas Heyer
Post by Jochen Kalmbach
Hast Du schon mal versucht Zeichen > 127 auszugeben?
(meine Behauptung bezieht sich im übrigen auf wprintf; vermutlich trifft es
aber auch auf wcout zu).
Stell doch mal die Schriftart auf "Lucida Console" um und -schwups-- wird
bei der Ausgabe das Eur-Zeichen dargestellt...
Lucida ändert nichts! Gibt nichts über Code 255! Absoluter Mumpitz.
Äh... das ganze ist ja auch ein Bug in der CRT...
Post by Andreas Heyer
Wenn die erste Zeile nicht auskommentiert wird, kommt man gar nicht bis
zur Schleife. Und die Schleife bricht nach 255 ab.
Wie gesagt... entweder drücke ich mich undeutlich aus, oder ...

***Es ist ein Bug in der CRT***




Also hier nochmals ein Beispiel:

<code>
#include <windows.h>
#include <stdio.h>
#include <iostream>

int _tmain(int argc, _TCHAR* argv[])
{
// Should output: "AaCcDdEe" (with macron, actute, caron, macron)
wchar_t c[] = {0x0100, 0x0101, 0x0106, 0x0107, 0x010E, 0x010F, 0x0112,
0x0113, '\n', 0x0000};
wprintf(L"wprintf: %s", c); // => BUG (stops after "wrpintf: " !)
std::wcout << L"wcout: " << c; // => BUG (stops after "wcout: " !)
DWORD written; // => The following works correctly:
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), c, sizeof(c)/sizeof
(wchar_t), &written, NULL);
return 0;
}
</code>


Hier werden 3 verschiedene Arten der Ausgaben gemacht:
1. wprintf => BUG: gibt nichts aus
2. wcout => BUG: gibt nichts aus
3. WriteConsoleW => Ok

Wenn Du jetzt hier die "normale" Console verwendest, dann siehst Du bei der
dritten Ausgabe nur "AaCcDdEe"!

Dies ist aber _nicht_ korrekt!

Stelle bitte den Font der Console *bevor* du das Programm startest auf
"Lucida Console" um und (_staun_) wirst Du feststellen, dass die korrekten
Zeichen dargestellt werden (nämlich die obigen nur mit "Akzenten" (oder wie
heissen die komischen Striche?).



Fazit:
In der CRT sind schon immer diese Bugs drin, aber es scheint so als ob sich
niemand dafür interessiert. Vermutlich werden diese Bugs auch noch in
VS2005 drin sein.

Windows sollte zukünftig in der Standard-Consolen-Schriftart alle Zeichen
drin haben..
--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Andreas Heyer
2004-10-19 06:05:25 UTC
Permalink
Hallo Jochen,
Post by Jochen Kalmbach
Wie gesagt... entweder drücke ich mich undeutlich aus, oder ...
***Es ist ein Bug in der CRT***
In der CRT sind schon immer diese Bugs drin, aber es scheint so als ob sich
niemand dafür interessiert. Vermutlich werden diese Bugs auch noch in
VS2005 drin sein.
Wie macht denn die CRT ihre Ausgaben? Die nehmen wohl nicht
WriteConsoleW()? Das ist mir ehrlich gesagt suspekt ;-) Und dabei ist
die CRT mittlerweile Bestandteil von Windows und muss nicht einmal
installiert werden...
Wie ich schon sagte: MS ist nicht zu verstehen! Die sollten wirklich
mal ein paar "Bug-Slayer" zusätzlich einstellen. Aber den Gerüchten
nach blickt ja kaum noch jemand Durchblick im MS-Code.

MfG
Andreas
Jochen Kalmbach
2004-10-19 06:18:43 UTC
Permalink
Hallo Andreas,
Post by Andreas Heyer
Post by Jochen Kalmbach
***Es ist ein Bug in der CRT***
In der CRT sind schon immer diese Bugs drin, aber es scheint so als ob sich
niemand dafür interessiert. Vermutlich werden diese Bugs auch noch in
VS2005 drin sein.
Wie macht denn die CRT ihre Ausgaben? Die nehmen wohl nicht
WriteConsoleW()?
Die CRT hat sich gedacht: "Ich bin ganz intelligent... ich verwenden einen
Ausgabepuffer (der aber leider nur ASCII kann), damit die Ausgabe schneller
wird"

Also: Es wird ein internen Puffer verwendet, der nur ASCII kann. Somit wird
jedes wchar_t-Zeichen wieder nach ASCII zurückgewandelt!
Dies geht aber in der Default-Locale ("C") nur für Zeichen zwischen 0 und
127!!!

Kommt ein whcar_t-Zeichen > 127 vor, so wird die Ausgabe abgebrochen.
--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Andreas Heyer
2004-10-19 06:31:34 UTC
Permalink
Hallo Jochen,
Post by Jochen Kalmbach
Die CRT hat sich gedacht: "Ich bin ganz intelligent... ich verwenden einen
Ausgabepuffer (der aber leider nur ASCII kann), damit die Ausgabe schneller
wird"
LOL
Post by Jochen Kalmbach
Also: Es wird ein internen Puffer verwendet, der nur ASCII kann. Somit wird
jedes wchar_t-Zeichen wieder nach ASCII zurückgewandelt!
Dies geht aber in der Default-Locale ("C") nur für Zeichen zwischen 0 und
127!!!
Kommt ein whcar_t-Zeichen > 127 vor, so wird die Ausgabe abgebrochen.
Da liegt die Lösung IMHO nahe: Einen wchar_t-Puffer nehmen und alle
ASCII/ANSI-Zeichen nach UNICODE wandeln. Und das bekommt keiner bei MS
hin??? Wenn eh Win95/98/ME obsolet sind, dann kann man sich doch voll
auf die UNICODE-Fähigkeiten von NT verlassen. Oder alternativ zwei CRT
für Win9x und NT.

MfG
Andreas
Carsten Witte [MVP]
2004-10-19 12:13:17 UTC
Permalink
Björn Dehmel wrote in
Post by Björn Dehmel
Sie sind EBCDIC gespeichert, das ist richtig.
Hehe, habe gerade den Newsserver gewechselt, jetzt sehe ich auch den
Rest vom Thread. Aber obwohl augenscheinlich nur noch das Problem mit
dem Codesoleoutput uebrig ist, wollte ich Dir noch

http://www.iseriesnetwork.com/Resources/ClubTech/TNT400/best_of_as400_newsgroups.htm

ans Herz legen, falls Du es noch nicht kennst.

Carsten Witte [MVP]
--
mpdvc-FAQ: http://www.mpdvc.de
Newssuche: http://groups.google.com/advanced_group_search
Private : http://www.carsti.de/dmfc.html

Ich beantworte keine Fragen, die per e-mail eingehen!
Jochen Kalmbach
2004-10-18 12:17:46 UTC
Permalink
Post by Jochen Kalmbach
Man beachte aber, dass auf einer AS400 die Codierung i.d.R. in
EBCDIC erfolgt...
Poste doch mal ein paar bytes in der entsprechenden codierung und was
rauskommen soll!

So in der Art:
unsigned char input[] = 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??
unsigned char ouput[] = ...
--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Björn Dehmel
2004-10-18 11:21:02 UTC
Permalink
Das ist eine sehr gute Idee, das muss ich gleich mal ausprobieren.
Post by Jens Geyer
Hallo *,
Post by Jochen Kalmbach
Post by Björn Dehmel
Wir haben in unserer Datenbank (AS400) Strings in polnischer Sprache
gespeichert, die ich gerne korrekt auf dem PC (Windows XP deutsch)
anzeigen lassen möchte. Wie macht man das?
1. Du musst rausfinden in welcher Kodierung die Strings vorliegen
(also in welcher Codepage)
ACK. Polnisch verwendet üblicherweise die Windows-1250
Post by Jochen Kalmbach
2. Dann wandle den eingabestring z.B: via "MultiByteToWideChar"
nach UNICODE um
Oder erzeuge alternative einen Font mit dem passenden Charset, für Polnisch
wäre das das EASTEUROPE_CHARSET.
Post by Jochen Kalmbach
3. Zeige die Strings dann an
Für Unicode kannst Du ohne weitere Maßnahmen TexOut32W auf
nicht-NT-Plattformen wie 95/98/ME verwenden.
Für die Ausgabe als normaler (lies: nicht Unicode) String mit dem genannten
Font kannst Du hingegen alle verfügbaren Funktionen verwendn, handelst Dir
damit aber wieder andere Probleme ein.
Viele Wege führen in's ROM, jetzt mußt Du nur noch den für deinen
Anwendungsfall am besten geeigneten finden.
JensG
Björn Dehmel
2004-10-20 10:25:02 UTC
Permalink
Post by Björn Dehmel
Wir haben in unserer Datenbank (AS400) Strings in polnischer Sprache
gespeichert, die ich gerne korrekt auf dem PC (Windows XP deutsch) anzeigen
lassen möchte. Wie macht man das?
Nach endlos langem Forschen und euren hilfreichen Beiträgen sind wir zu
folgemdem Zwischenstand gekommen:

Die polnischen Sonderzeichen liegen jenseits der 256 ANSI-Tabelle, wobei
natürlich nicht jeder Zeichensatz diese unterstützt. Dieses bedeutet, dass
man auf einem deutschen Rechner UNICODE mit der richtigen Schriftart
verwenden muss. Wandelt man so ein Zeichen über WideCharToMultiByte um,
bekommt man zwar ein Resultat, benötigt dafür aber den richtigen Zeichensatz,
da die Sonderzeichen zum Teil in den Bereich 0x40 - 0x7f gemapt werden.
Dieses wird bei einer deutschen Schriftart natürlich immer was anderes
anzeigen.

Wie die Daten von der AS400 kommen, haben wir noch nicht testen können, da
das komplette Programm erst mal auf UNICODE umgestellt werden muss.

Gruß Björn

Loading...