Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   AnsiString zu String zuweisen ohne Konvertierung? (https://www.delphipraxis.net/202776-ansistring-zu-string-zuweisen-ohne-konvertierung.html)

Rolf Frei 7. Dez 2019 11:25

Delphi-Version: 10.3 Rio

AnsiString zu String zuweisen ohne Konvertierung?
 
Wie kann ich in 10.3 Rio einen AnsiString einem String zuweisen, ohne dass der String über die Codepage konvertiert wird? Siehe folgendes Beispiel:

Delphi-Quellcode:
var
  a: AnsiString;
  s: String;
begin
  a := #$33#$95#$34;
  s := a;
end;
Nach der Zuweisung s := a hat s die Zeichenwerte #$0033 #$2022 #$0034. Ich müsste nun aber anstatt #$2022 den Wert #$0095 haben. Wie kann ich das bewerkstelligen, dass da bei der Zuweisung keine Codepagekonvertierung stattfindet? Auch die {$HIGHCHARUNICODE OFF} Direktive bringt keine Lösung.

scrat1979 7. Dez 2019 12:36

AW: AnsiString zu String zuweisen ohne Konvertierung?
 
Ich kann dir keine direkte Lösung sagen, aber die Suche auf Google Bei Google suchendelphi ansistring to string ergibt etliche Teffer. Vielleicht findest du da schnell eine Lösung :)

Rolf Frei 7. Dez 2019 12:56

AW: AnsiString zu String zuweisen ohne Konvertierung?
 
Habe schon Stunden lange gesucht und zu dem was ich hier suche finde ich nichts.

Das nächste Problem steht auch schon an: TIniFile/TMemeIniFile. Delphi liest hier nun Unicodestrings obwohl ein INI-File immer Ansi-Daten enthält. Nun habe ich da wieder das selbe Problem, dass ich da nun in Unicode umgewandelte Strings geliefert bekomme, die Zeichenwerte > 255 enhalten. Die Daten im INI sind aber als ANSI gespeichert und ich muss diese auch wieder in der selben Art lesen können, also nur mit Zeichewerten <=255. Ist im Prinzip genau ds selbe Problem, dass da beim Einlesen eine Konvertierung in Unicode passiert, was nicht sein darf! Ich brauche da die Ansi Strings so wie sie in Delphi 7 gespeichert wurden. Gibt es irgendwo ein Ansi kompatibles TIniFile?

hoika 7. Dez 2019 15:30

AW: AnsiString zu String zuweisen ohne Konvertierung?
 
Hallo,
schau mal hier, Stichwort Encoding
http://docs.embarcadero.com/products...TEncoding.html

TurboMagic 7. Dez 2019 15:47

AW: AnsiString zu String zuweisen ohne Konvertierung?
 
Eventl. statt AnsiString RawByteString benutzen, der "hat keine Codepage".

Grüße

TurboMagic

Rolf Frei 7. Dez 2019 15:49

AW: AnsiString zu String zuweisen ohne Konvertierung?
 
Das ist mir alles bekannt nützt mir hier nur nichts oder ich verstehe nicht wie man das richtig anwendet. Man müsste ja beim Unicodestring "s" sagen, dass er nichts umwandeln soll. Hast du mir eventuell ien Beispal anhandn meins Beispiels? Bei meinen Tests kam da nie das gewünschte heraus, wenn ich mit Tencoder herumgespielt habe.

Wenn ich "a" and "s" nicht direkt zuweise, sondern sowas hier mache..

Delphi-Quellcode:
 
  for i := 1 to Length(a) do
    s := s + Char(Ord(a[i]));
... bekomme ich das was ich will, aber das kann nicht der richtige Weg sein.

@TurboMagic
Das habe ich auch schon versucht macht aber keinen Unterschied. S hat danach immer den Unicodewert (2022) aus dem ANSI Zeichen 95 erhalten. Auch eine SetCodepage hat keinen Unterschied gemacht. Es müsste ja der Varibale S mitgetielt werden, das sie keine Uniccodekonvertierung machen soll. Das Encoding ist ja eher für das umgekehrte vom String in ein Ansi.

Dennis07 7. Dez 2019 18:20

AW: AnsiString zu String zuweisen ohne Konvertierung?
 
Mit
Delphi-Quellcode:
String
bzw.
Delphi-Quellcode:
UnicodeString
geht das so leider nicht, weil hier eine Konvertierung IMMER automatisch stattfindet (Deshalb sind
Delphi-Quellcode:
String
-Objekte auf der Linken Seite auch immer ReadOnly).
Das ist wegen der Referenzzählung notwendig, damit du keine Speicherlöcher bekommst. Allerdings gibt es hier ein paar möglichkeiten, das zu umgehen.
Der einfachste Weg wäre es, Statt
Delphi-Quellcode:
String
bzw.
Delphi-Quellcode:
UnicodeString
einen anderen Typ für die Zuweisung zu verwenden.
Ich würde einen Zeigertypen wie
Delphi-Quellcode:
PAnsiChar
oder alternativ
Delphi-Quellcode:
PByte
empfehlen.

Delphi-Quellcode:
var
  a: AnsiString;
  s: String;
begin
  a := #$95;
//  s := a;
  PAnsiChar(s) := PAnsiChar(a);
  ShowMessage((Ord(s[1]).ToHexString)); // Gibt $95 zurück
Allerdings bekommst du so für das zweite, dritte, vierte, ... Zeichen der Zeichenkette nur Salat heraus, da die Zeichen ja andere Bytegrößen haben. Das kannst du durch eine einfache Zuweisung nicht beheben, da du jedes Zeichen auf Unicode erweitern musst.

KLEINE ERGÄNZUNG: So könntest du es Implementieren, falls du die Werte Kopieren willst:
Delphi-Quellcode:
var
  a: AnsiString;
  s: String;
  pa: PAnsiChar;
  ps: PChar;
begin
  a := #$95#22;
  SetLength(s, length(a));
  pa := PAnsiChar(a);
  ps := PChar(s);
  while pa^ <> #0 do
  begin
    PAnsiChar(ps)^ := pa^;
    Inc(pa);
    Inc(ps);
  end;
  ShowMessage((Ord(s[2]).ToHexString)); // Gibt $16 zurück
end;

Uwe Raabe 7. Dez 2019 23:46

AW: AnsiString zu String zuweisen ohne Konvertierung?
 
Hast du schon mal daran gedacht, anstatt der Unicodestrings besser TBytes zu verwenden? Dann kann dir das Encoding nämlich völlig egal sein.

Wenn du deinen konkreten Anwendungsfall beschreiben könntest, und nicht nur das Symptom, dann könnte man vielleicht eine Lösung formulieren.

Dennis07 8. Dez 2019 01:37

AW: AnsiString zu String zuweisen ohne Konvertierung?
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1452941)
Hast du schon mal daran gedacht, anstatt der Unicodestrings besser TBytes zu verwenden? Dann kann dir das Encoding nämlich völlig egal sein.

Ist ja quasi was ich geschrieben habe. Nur wirst du mit TBytes das selbe Problem haben wie mit PAnsiChar@UnicodeString, nämlich, dass du nicht richtig darauf zugreifen kannst, wenn du die Anpassung der Byte-Offsets nicht vornimmst. Es gibt sicher auch eine Funktion dafür, die mir allerdings zum jetzigen Zeitpunkt nicht bekannt ist.

Rolf Frei 8. Dez 2019 03:13

AW: AnsiString zu String zuweisen ohne Konvertierung?
 
@Dennis07
Herzlichen Dank für deine Erklärung. Dann gibt es also keine Möglichkeit das ohne "Aufwand" zu lösen. Meine for-Schlauefe würde dann ja auch das mache was ich will und wäre viel einfacher, als dein Code. Vermutlich aber auch etwas langsamer. Das wäre hier aber keine Problem, da diese Routine nur sehr vereinzelt aufgerufen wird.

Ich mache nun sowas in der Art:
Delphi-Quellcode:
var
  a: AnsiString;
  s: String;
begin
  a := #$33#$95#$34;
  SetLength(s, Length(a));
  for i := 1 to Length(a) do
    s[i] := Char(Ord(a[i]));
end;
Damit kann ich leben und sollte für meine Zwecke auch schnell genug sein.

@Uwe Raabe
Ja an TBytes habe ich schon gedacht, aber das dann auch recht schnell wieder verworfen, das das sonst zu umständlich wäre, diese Funktion in der ich das so brauche, aufzurufen. Müsste ja dann von extern in ein TBytes umgewandelt werden. Ich möchte der Funktion aber ein String übergeben, damit das nicht bei jedem Aufruf der Funktion so umständlich wird.

Was mir aber immer noch Probleme macht, ist das TIniFile, das mir die ANSI Werte falsch liefert. Kann da zwar TMemIniFile mit Angabe einer Encoding verwenden, das hat aber meines erachtens zu viel Overhead, da damit immer das ganze File verabeitet wird. Wenn ich nur einen einzlnen Wert schreiben/lesen will, ist das nicht gerade optimal. Da müsste auch ein Read-/WriteAnsiString existieren um das Problem zu lösen. Dass es das nicht gibt empfinde ich schon als grober Fehler in der TIniFile Implementation, da es so nicht möglich ist einen sauberen AnsiString zu erhalten. Da beim Einlsenen der Werte diese in einen Unicodestring umgewandelt werden, werden diverse Zeichen in einen Wert > 255 umgewandelt und mit diesen kann ich nicht weiter arbeiten, da meine Routine verlangt, dass da nur 1-Byte Zeichen (Werte 0-255) kommen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:23 Uhr.
Seite 1 von 4  1 23     Letzte »    

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz