Entwickler-Ecke
Sonstiges (Delphi) - ä, ö, üs in ACII geht nicht!?
Killi - Fr 24.10.03 15:12
Titel: ä, ö, üs in ACII geht nicht!?
Hi!
Es geht um folgendes problem: Ich lese eine Krankenkassenkarte mit TSmartCard aus, Beispiel-Code war dabei, damit kann ich nix anfangen, habe es eben drin gelassen - Daten werden auch wunderbar gelesen, allerdings gibt es auch Karten auf denen der Name mit Umlauten, also ä,ö und üs geschrieben wird - hier bekomme ich nur ein "{"...wie kann ich das verhindern? Liegt es etwa daran (?):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75:
| procedure TFKarte.ExecSCardCmd(Cmd,DataIn: String); const BufferSize = 32768; var P,pDataIn: PChar; DataASCII, DataHex, DataInHex: String; C: Integer; Len, LenIn: LongInt; begin MemoDataOut.Clear; if (Cmd = '') then begin MemoDataOut.Lines.Add('no command'); exit; end; with EditDataIn do if ((Font.Color=clRed) and (Text='(nil)')) then DataIn:=''; ShowCommand(Cmd,DataIn); P:=AllocMem(BufferSize); if DataIn='' then begin pDataIn:=nil; LenIn:=0; end else begin if RadioButtonHEX.Checked then begin DataInHex:=HexStrToTxt(DataIn); EditDataIn.Text := TxtToHexStr(DataInHex); LenIn := Length(DataInHex); pDataIn:=@DataInHex[1]; end else begin LenIn := Length(DataIn); pDataIn:=@DataIn[1]; end; end;
try
Len:=SmartCard.Comand(Cmd,pDataIn,LenIn,P,BufferSize);
if Len <> 0 then begin
DataASCII:=''; for C:=0 to Len-1 do begin case P[C] of #0..#31: DataASCII:=DataASCII+'°'; else DataASCII:=DataASCII+P[C]; end; end; if DataASCII <> '' then begin MemoDataOut.Lines.Add(DataASCII); end; end; except on E:ESmartCard do begin MemoDataOut.Lines.Add(' '); MemoDataOut.Lines.Add('SmartcardException: '+E.Message); end; on E:Exception do begin MemoDataOut.Lines.Add(' '); MemoDataOut.Lines.Add('Exception: '+E.Message); end; end; FreeMem(P,BufferSize); end; |
Hoffe ihr könnt mir helfen....
Wolff68 - Fr 24.10.03 18:35
Generell könnte es an der verwendeten Schriftart liegen, da ASCII-Codes über 128 nicht "genormt" sind.
Ebenso kann es sein, daß aus Speicherplatzgründen die Zeichen auf der Karte in nur 4 Bits gespeichert werden (Also nur ASCII 0-128 zulässt)
So könnte zB aus einem ü eine { werden... (oder hab ich mich jetzt verrechnet?)
Du könntest aber mal nachsehen, welche ASCII-Codes Du von der Karte überhaupt bekommst.
Ä= 196
Ö= 214
Ü= 220
ä= 228
ö= 246
ü= 252
ß= 223
{= 123
Delete - Fr 24.10.03 19:22
Ich glaube nicht, dass die Zeichen nur mit 4 Bits codiert sind. Wie willst du sonst Müller von Mueller unterscheiden? Soll es nämlich auch geben.
Killi - Mi 29.10.03 10:06
Hi!
Die Theorie von Wolff68 könnte stimmen, da ich die Umlaute etc. schon als ~ zurückbekomme - und meine LÖSUNG für das Problem stimmt auch, ich ersetzte #225 durch ß, dann kommt die Straße richtig - allerdings werden ja äs, ös und üs auch mit einem ~ gekennzeichnet - und hie ist mein Problem, es kommen anscheinend keine Datensätze über #128 an...d.h. ich bekomme immer nur ein ~ schon im ASCII-Code.....
Kann das am Treiber liegen??? Weil das kartenlesegerät müsste es können...von der Firma gibts auch eine Krankenkassenlösung die das kann....ich versteh gar nix mehr!
Maggi - Mi 29.10.03 14:11
Hi,
kann es sein das du ineinem ganz anderen Zeichensatz unterwegs bist.
OEM oder so, dann mußt du erst konvertieren und alles wird gut. Wird auch in der Hilfe sehr gut beschrieben!
Gruß
Maggi
Killi - Mi 29.10.03 14:37
OEM Zeichensatz sagt mir leider nix, hab keine Ahnung wie die Daten codiert sind - guck dir oben mal meinen Code an, is rauskopiert - das macht den ganzen sch...! Aber da steht nur was von ASCII zu norml. Text!?
Also...!!??
Killi - Do 30.10.03 12:01
kann mir keiner mehr helfen? :(
Spieler1 - Do 30.10.03 23:57
Das geht schon, du musst nur ein unsigned char verwenden, da sind dann auch solche Sonderzeichen drin.
Killi - Fr 31.10.03 10:13
unsigned??? Wie mach ich das? Kann ja fast nix mit der Prozedur anfangen...kannst du mir helfen?
Ja-Pa - Fr 31.10.03 13:46
Maggi hat folgendes geschrieben: |
OEM oder so, dann mußt du erst konvertieren und alles wird gut. |
Dieses Problem habe ich auch, wenn ich ActiveX-Controls einen String übergeben will.
Der hängt sich bei Sonderzeichen dann auf.
Vielleicht muss ich das auch konvertieren?
Wie mache ich das?
Gruß, Ja-Pa
Spieler1 - Fr 31.10.03 13:49
Sorry, hab vergessen, dass das ein Delphi Forum ist und ich kein Delphi kann.
Den Typ unsigned char gibt es in C/C++, da kann man einfach schreiben:
Quelltext
1:
| unsigned char meinString[100]; |
Dann hat man einen String, in dem 255 (glaub ich) verschiedene Zeichen vorkommen können, ein normaler char hat nur die Hälfte. Vielleicht hilft dir das ja auch bei Delphi irgendwie :? .
:D
Maggi - Fr 31.10.03 13:52
Hi,
Schau doch mal in der Hilfe unter "OemToAnsi" nach in der Gegend findest du einige Fkt die dir vielleicht weiter helfen!! :lol:
Gruß
Maggi
Killi - Mo 03.11.03 12:19
Das bringt mich doch alles nicht weiter, ich weiß genau dass ich die Daten in ASCII bekomme...ist etwas an der ASCII-Funktion falsch? Bekomme ja keinen Wert wie 255 oder so....weiß nicht mehr weiter!!!
Brueggendiek - Mo 03.11.03 23:47
Hallo Killi!
Nach der beliebten Winzig-Weich-Methode "Halte Dich nie an bestehende Standards, was WinzigWeich sagt, ist der neue Standard" hat der große Billy-Boy-Gates-jetzt-endlich beschlossen, daß Windows nicht mit dem ASCII-Code, sondern mit dem ANSI-Code arbeitet. Damit ist per WinzigWeicher Verfügung der bisherige Standard ASCII ungültig.
ASCII ist im Original ein 7-Bit-Code. Früher wurde bei Modem-Übertragung oft noch ein Paritätsbit verwendet, man übertrug 7 Bit + Parität, also 8 Bit zusammen.
Inzwischen gibt es einen ASCII-Standard, der mit 8 Bit arbeitet und damit auch so schöne Dinge wie Umlaute und Rahmengrafik (Blockgrafik) enthält.
Der ANSI-Code von Windows entspricht in den ersten 128 Zeichen dem ASCII-Code (7-Bit-Code). Die Zeichen ab $80 werden jedoch komplett anders belegt und sind somit nicht kompatibel zu ASCII. Insbesonders fehlen die Blockgrafikzeichen.
Bei Windows wird der ASCII-Zeichensatz als OEM-Zeichensatz bezeichnet. Damit sollte die Funktion "OEMtoANSI" einen ASCII-String - soweit die Zeichen definiert sind - in den Windows-Zeichensatz umwandeln.
Wenn Du Sicher bist, daß es ASCII ist, sollte die genannnte Funktion helfen. Wenn nicht, hilft nur das Ausprobieren, d.h. Karten mit Umlauten in den Namen organisieren und nachsehen, was da kommt. Dann mit Stringreplace oder durch zeichenweises Bearbeiten eine eigene Umwandlung realisieren.
Gruß
Dietmar Brüggendiek
Killi - Di 04.11.03 11:50
Danke für die klärende Antwort!
Strreplace hätt ich schon lange gemacht, (bin ja faul) aber das geht eben nicht, da lles als "}" angezeigt wird, ist ja die sch...! Gut, ich teste es mal mit OEMToANSI!
Killi - Di 04.11.03 12:26
Titel: hm...
...hier der neue Code, vielleicht hab ichs ja auch falsch eingebunden, OEMtoANSI steht jetzt VOR der "normalen" Textausgabe, aber es tut sich gar nix:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118:
| procedure TFormMain.ExecSCardCmd(Cmd,DataIn: String); const BufferSize = 32768; var P,pDataIn: PChar; DataASCII, DataHex, DataInHex: String; C: Integer; Len, LenIn: LongInt; begin MemoDataOut.Clear; if (Cmd = '') then begin MemoDataOut.Lines.Add('no command'); exit; end; with EditDataIn do if ((Font.Color=clRed) and (Text='(nil)')) then DataIn:=''; ShowCommand(Cmd,DataIn); P:=AllocMem(BufferSize); if DataIn='' then begin pDataIn:=nil; LenIn:=0; end else begin if RadioButtonHEX.Checked then begin DataInHex:=HexStrToTxt(DataIn); EditDataIn.Text := TxtToHexStr(DataInHex); LenIn := Length(DataInHex); pDataIn:=@DataInHex[1]; end else begin LenIn := Length(DataIn); pDataIn:=@DataIn[1]; end; end;
MemoDataOut.Lines.Add('executing command....'); try
Len:=SmartCard.Comand(Cmd,pDataIn,LenIn,P,BufferSize);
if Len = 0 then begin MemoDataOut.Lines.Add('command successful'); end else begin MemoDataOut.Font.Name:='Courier'; MemoDataOut.Font.Style:=[]; MemoDataOut.Lines.Add('DataOut in HEX:'); MemoDataOut.Lines.Add(' '); DataHEX:=''; for C:=0 to Len-1 do begin DataHEX:=DataHEX+IntToHex(Ord(P[C]),2)+' '; if (Length(DataHex)=48) then begin DataHEX:=DataHEX+' ['+IntToStrEx(C,3)+']'; MemoDataOut.Lines.Add(DataHEX); DataHEX:=''; end; end; if DataHEX <> '' then begin while Length(DataHEX)<49 do DataHEX:=DataHEX+' '; DataHEX:=DataHEX+'['+IntToStrEx(C,3)+']'; MemoDataOut.Lines.Add(DataHex); end; MemoDataOut.Lines.Add(' '); MemoDataOut.Lines.Add('DataOut in ASCII:'); MemoDataOut.Lines.Add(' '); DataASCII:='';
OEMtoAnsi(P, P); for C:=0 to Len-1 do begin case P[C] of #0..#31: DataASCII:=DataASCII+'°';
else DataASCII:=DataASCII+P[C]; end; if ((Length(DataASCII)>32) or (P[C]=#13)) then begin if (P[C]=#13) then begin while Length(DataASCII)<37 do DataASCII:=DataASCII+' '; DataASCII:=DataASCII+'(#13 found) '; end else while Length(DataASCII)<49 do DataASCII:=DataASCII+' '; MemoDataOut.Lines.Add(DataASCII+'['+IntToStrEx(C,3)+']'); DataASCII:=''; end; end; if DataASCII <> '' then begin while Length(DataASCII)<49 do DataASCII:=DataASCII+' '; MemoDataOut.Lines.Add(DataASCII+'['+IntToStrEx(C,3)+']'); end; end; except on E:ESmartCard do begin MemoDataOut.Lines.Add(' '); MemoDataOut.Lines.Add('SmartcardException: '+E.Message); end; on E:Exception do begin MemoDataOut.Lines.Add(' '); MemoDataOut.Lines.Add('Exception: '+E.Message); end; end; FreeMem(P,BufferSize); end; |
Moderiert von
tommie-lie: Code- durch Delphi-Tags ersetzt
elysm - Mi 05.11.03 10:58
Zitat: |
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| for C:=0 to Len-1 do begin case P[C] of #0..#31: DataASCII:=DataASCII+'°';
// #132: DataASCII:=DataASCII+'ä'; // #142: DataASCII:=DataASCII+'Ä'; // #129: DataASCII:=DataASCII+'ü'; // #154: DataASCII:=DataASCII+'Ü'; // #148: DataASCII:=DataASCII+'ö'; // #153: DataASCII:=DataASCII+'Ö'; // #225: DataASCII:=DataASCII+'ß'; else DataASCII:=DataASCII+P[C]; | |
nimm doch einfach mal die slash´s vor den angaben weg!! das wäre das erste gewesen was ich gemacht hätte!
es sei den du hast die dahin gemacht.. denn hab ich nix gesagt! ;)
Killi - Mi 05.11.03 11:37
die hab ich dahin gemacht weils nix bringt......das is ja die scheibenwischanlage
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!