XML und Sonderzeichen in C++ (immer noch offen!!)
-
Hallo
Nein den die von dir gezeigte Umwandlung ist ja gerade Codepage-abhängig. Hast du einen Widestring mit einem deutschen "ä", kannst du diesen auf einem System mit einer Codepage ohne dem "ä" nicht umwandeln... (ä kann durch beliebige Zeichen aus Arabisch, Hebräisch, Kyrillisch ersetzt werden).
Erst mit UTF8 kannst du die Unicode-Zeichen der meisten Sprachen unabhängig von Codepages umwandeln. Das bedeutet aber auch das die so kodierten AnsiStrings aus Kombinationen von Zeichen bestehen die ohne Rückumwandlung keinen Sinn ergeben, selbst wenn die Zeichen selber einfach in das Wide-Äquivalent umgewandelt werden.Hier mal die entsprechende Funktion aus Tnt um UTF8-AnsiString in WideString umzuwandeln. (Ich hoffe ich habe alles erwischt)
function Utf8Decode(const S: UTF8String): WideString; function Utf8ToUnicode(Dest: PWideChar; MaxDestChars: Cardinal; Source: PAnsiChar; SourceBytes: Cardinal): Integer; var i, count: Cardinal; c: Byte; wc: Cardinal; begin if Source = nil then begin Result := 0; Exit; end; Result := -1; count := 0; i := 0; if Dest <> nil then begin while (i < SourceBytes) and (count < MaxDestChars) do begin wc := Cardinal(Source[i]); Inc(i); if (wc and $80) <> 0 then begin if i >= SourceBytes then Exit; // incomplete multibyte char wc := wc and $3F; if (wc and $20) <> 0 then begin c := Byte(Source[i]); Inc(i); if (c and $C0) <> $80 then Exit; // malformed trail byte or out of range char if i >= SourceBytes then Exit; // incomplete multibyte char wc := (wc shl 6) or (c and $3F); end; c := Byte(Source[i]); Inc(i); if (c and $C0) <> $80 then Exit; // malformed trail byte Dest[count] := WideChar((wc shl 6) or (c and $3F)); end else Dest[count] := WideChar(wc); Inc(count); end; if count >= MaxDestChars then count := MaxDestChars-1; Dest[count] := #0; end else begin while (i < SourceBytes) do begin c := Byte(Source[i]); Inc(i); if (c and $80) <> 0 then begin if i >= SourceBytes then Exit; // incomplete multibyte char c := c and $3F; if (c and $20) <> 0 then begin c := Byte(Source[i]); Inc(i); if (c and $C0) <> $80 then Exit; // malformed trail byte or out of range char if i >= SourceBytes then Exit; // incomplete multibyte char end; c := Byte(Source[i]); Inc(i); if (c and $C0) <> $80 then Exit; // malformed trail byte end; Inc(count); end; end; Result := count + 1; end; var L: Integer; Temp: WideString; begin Result := ''; if S = '' then Exit; SetLength(Temp, Length(S)); L := Utf8ToUnicode(PWideChar(Temp), Length(Temp)+1, PAnsiChar(S), Length(S)); if L > 0 then SetLength(Temp, L-1) else Temp := ''; Result := Temp; end;bis bald
akari
-
Hm leider wurde mein Problem immer noch nicht behoben!
Also wenn ich den Node mit der Funktion NodeValue auslesen lasse und den dann mit der utf8encode bzw utf8toansi Funktion encoden lasse, geschieht leider nichts, also die %7E Zeichen oder so bleiben drin.Was nun?!
-
Hallo
Dann ist es wohl kein richtiges UTF8-Zeichen. Vielleicht soll es so sein? Weist du denn was es uncodiert bedeuten soll?
bis bald
akari
-
Ich meine das %7E müsste ein ° sein.
Oder %20 halt wie bekannt ein Leerzeichen usw...
Wollste nun etwa da drauf hinaus, eine Funktion zu schreiben um alle Zeichen zu ersetzen?
-
du brauchst einen URI Encoder da die Zeichen Escaped sind.
z.B. das %7E ist ein ~ Zeichenhier eine kleine Beschreibung
http://www.w3.org/International/O-URL-code.htmlund hier die Lösung:
http://www.codeguru.com/cpp/i-n/internet/http/article.php/c12759/
-
Vielen Danke, Borland hat die Funktion URLDecode() bereits und die erfüllt meinen Wunsch!

MfG
TheCaleb
-
Hm die URLDecode- Funktion ist bei der 2006er Version von Borland nur noch im Indy- Package enthalten und ich habe keine Ahnung, wie ich das anwenden sollte.
Zudem fiel mir auf, dass Ä Ö Ü garnicht decodiert werden.
Gibt es andere Funktionen die das können, also UTF-16 decodieren?!
Oder gibt es vielleicht sofort ne Möglichkeit über XML Funktionen von einem NodeValue oder so auf einen dekodierten String zu kommen?
-
@ Akari hast du keine Idee, welche Funktion ich nutzen kann oder lässt du diesen Beitrag absichtlich links liegen, da dieses Thema schonmal behandelt wurde?
Ich brauche halt Hilfe, da ich keine Funktionen finden kann oder die von Indy(leider ohne ÄÖÜ) nicht einbinden kann...Bitte helft mir doch weiter!!

-
URLDecode() war doch schon immer nur im Indy-Package mit drin. Das sollte doch auch im 2006er Builder mit dabei sein.
-
Ja ist es auch aber ich versteh nicht so ganz, wie ich diese Funktion einbinden kann, denn sonst ging das immer einfach so, dass ich diese Funktion einfach anwenden musste.
Gibt es nicht auch noch zufällig andere Funktionen, die ebenfalls auch das Ä Ü Ö dekodieren?
-
Also wie ich in der beigehängten Borland Hilfe sehen kann, ist die URLDecode keine Funktion, sondern eine Methode geworden, doch wie konnte man nochmal ein Object einer Klasse erstellen also wie konnte man die Klasse nochmal einbinden?
Borland Hilfe:
Indy.Sockets version 10.1.1.
URLDecode Method
Declaration
class function URLDecode(
ASrc: string
): string;
Parameters
Parameters Description
ASrc URL-encoded string to be decoded.Returns
String - The un-encoded ASCII representation of the URL.
Summary
Converts a URL-Encoded string to a US-ASCII string.
Description
URLDecode is a string class function that converts the URL-encoded string in ASrc to its representation in the US-ASCII character set. URLDecode is based on the URL character encoding rules as described in the Internet Standards document:
RFC 1738 - Uniform Resource Locators (URL)URLDecode can used to reverse any string encoding performed using URLEncode.
URLDecode converts all occurrances of the '+' character to ' ' (Space) (Decimal 32). URLDecode reads any values represented as a hexadecimal character triplet consisting of the "%" character followed by the two-digit hexadecimal value for the octet, and returns the value to its US-ASCII representation.
Example
AString := TIdURI.URLDecode(AURLString);
See Also
TIdURI.URLEncode
Class
TIdURI
-
Hallo,
Du mußt einfach ein Objekt vom Typ TIdURI erstellen. Dann kannst du dessen Membermethode nutzen. Etwa so
TIdURI* uri = new TIdURI; AnsiString decode = uri->URLDecode(code); // delete uri dann nicht vergessen
-
Danke, ich habe jetzt folgendes geschrieben:
TIdURI* uri = new TIdURI('asd'); uri->URLDecode("ads");Doch angeblich müsste ich noch einen weiteren Parameter angeben, erst TMetaClass, dann erst mein String:
[C++ Error] Unit1.cpp(70): E2034 Cannot convert 'char *' to 'TMetaClass *'
[C++ Error] Unit1.cpp(70): E2342 Type mismatch in parameter 'vmt' (wanted 'TMetaClass *', got 'char *')Doch was ist eine Variabel von TMetaClass oder so?!
Bzw wie müsste das dann aussehen?
-
Ich brauche immer noch Hilfe
-
Ok, ich hab mir mal die Headerdatei dazu angeschaut. Die Deklaration sieht so aus.
static AnsiString __fastcall URLDecode(TMetaClass* vmt, AnsiString ASrc);Wie man sieht, ist die Funktion statisch (benötigt also kein zusätzliches Objekt) und der Konstruktor benötigt zwei Parameter.
Der Aufruf müsste also so aussehen (ungetestet)TIdURI::URLDecode(__classid(TIdURI), "ads");
-
Wenn ich den Aufruf
TIdURI::URLDecode(__classid(TIdURI), "ads");schreibe, dann treten folgende Fehler auf:
[Linker Error] Error: Unresolved external 'Iduri::TIdURI::' referenced from ...UNIT1.OBJ
[Linker Error] Error: Unresolved external '__fastcall Iduri::TIdURI::URLDecode(System::TMetaClass *, System::AnsiString)' referenced from ...UNIT1.OBJWenn ich dann die Indy10 einbinde, dann treten mehrere Fehler in der Datei HTTPApp.hpp auf, diese Datei nutze ich hingegen nicht bewußt:
[C++ Error] Httpapp.hpp(94): E2293 ) expected
[C++ Error] Httpapp.hpp(983): E2189 extern variable cannot be initialized
[C++ Error] Httpapp.hpp(983): E2449 Size of 'ExtractHeaderFields' is unknown or zero
[C++ Error] Httpapp.hpp(983): E2188 Expression syntax
[C++ Error] Httpapp.hpp(983): E2293 ) expected
[C++ Error] Httpapp.hpp(984): E2189 extern variable cannot be initialized
[C++ Error] Httpapp.hpp(984): E2449 Size of 'ExtractHTTPFields' is unknown or zero
[C++ Error] Httpapp.hpp(984): E2188 Expression syntax
[C++ Error] Httpapp.hpp(984): E2293 ) expected
[C++ Warning] Unit1.cpp(96): W8004 'NodeList' is assigned a value that is never used
[C++ Error] Unit1.cpp(183): E2096 Illegal structure operation
[C++ Error] Unit1.cpp(319): E2096 Illegal structure operation
[C++ Error] Unit1.cpp(473): E2096 Illegal structure operation
[C++ Error] Unit1.cpp(584): E2096 Illegal structure operation
-
Die erste Fehlermeldung wird durch eine fehlende lib verursacht.
Versuche doch mal Indy9 statt 10 zu verwenden. Soweit ich weiß funktioniert Indy10 nicht richtig.
Ich spreche hier aber nicht aus Erfahrung, da ich die Indy-Bibliotheken noch nie verwendet habe.
-
Wenn ich die Indy9 einbinde treten die ersten beiden Fehler auf!
-
Was kann ich machen, sodass ich diese Funktion benutzen kann oder einfach irgendwas, sodass ich meinen Text decodieren kann?!
-
Hallo
Zumindestens das hier kompiliert :
TIdURI* uri = new TIdURI(0); AnsiString Text = uri->URLDecode(__classid(TIdURI), "ads"); delete uri;bis bald
akari