Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Memo.Text := Ansistring? nur wie (https://www.delphipraxis.net/127085-memo-text-%3D-ansistring-nur-wie.html)

emsländer 7. Jan 2009 15:15


Memo.Text := Ansistring? nur wie
 
Salvete,

Ich bekomme wegen dem Ansikram graue Haare.
Wie bekomme ich den Inhalt eines Ansistring in z.B. Memo.text oder eine normale string-Variable und umgekehrt?

D2009 ist da ja recht brutal!

Gruss

EL

SirThornberry 7. Jan 2009 15:23

Re: Memo.Text := Ansistring? nur wie
 
Ich würde es mit move probieren. Wenn der String jedoch ein Unicodestring ist sollte es mit CharToWideChar oder so ähnlich funktionieren.

mkinzler 7. Jan 2009 15:32

Re: Memo.Text := Ansistring? nur wie
 
Du kannst einer Stringvariablen problemlos einen AnsiString zuweisen. Umgekehrt kann es natürlich Probleme geben

emsländer 7. Jan 2009 15:45

Re: Memo.Text := Ansistring? nur wie
 
Zitat:

Zitat von mkinzler
Du kannst einer Stringvariablen problemlos einen AnsiString zuweisen. Umgekehrt kann es natürlich Probleme geben

nö - geht in der Form leider nicht. Da kommt nur MMüll bei rum, weil der Inhalt des Ansistrings ein verschlüsseter Text ist!

auch mit move geht es nicht - kracht mit einer Access Violation weg.

Delphi-Quellcode:
  if odlg.Execute then begin
    fs := TFileStream.Create(odlg.FileName, fmOpenRead    or fmShareDenyWrite);
    fs.Position := 0;   // File in den String-Stream schreiben
    sstream := TStringStream.Create;
    sStream.CopyFrom(fs,fs.size);  
    ansitmp := sStream.DataString;
    move(ansitmp,stmp,length(ansitmp));
    memo1.text := stmp;
    freeandnil(sstream);
    freeandnil(fs);
  end;
wie bringe ich das in eine lauffähige Version?

Gruss

EL

Luckie 7. Jan 2009 16:30

Re: Memo.Text := Ansistring? nur wie
 
Zitat:

Zitat von emsländer
nö - geht in der Form leider nicht. Da kommt nur MMüll bei rum, weil der Inhalt des Ansistrings ein verschlüsseter Text ist!

Kann es sein, dass die Zeichenkette nicht darstellbare Zeichen, wie zum Beispiel Steuerzeichen, enthält?

jbg 7. Jan 2009 16:31

Re: Memo.Text := Ansistring? nur wie
 
[quote="emsländer"]
Delphi-Quellcode:
  if odlg.Execute then begin
    fs := TFileStream.Create(odlg.FileName, fmOpenRead    or fmShareDenyWrite);
    fs.Position := 0;   // File in den String-Stream schreiben
Das ist ja wie "Query.Open;Query.First". Wo steht man denn wohl, wenn man die Datei gerade geöffnet hat.


Zitat:

Delphi-Quellcode:
    sstream := TStringStream.Create;

TStringStream ist bereits ein Unicode-String-Stream. Das wird so also nicht klappen, außer du hast einen UTF16 Text in der Datei.

Warum nicht einfach so einlesen:
Delphi-Quellcode:
var
  Stream: TFileStream;
  AnsiTemp: AnsiString;
begin
  ...
  Stream := TFileStream.Create(odlg.FileName, fmOpenRead or fmShareDenyWrite);
  try
    SetLength(AnsiTemp, Stream.Size);
    if AnsiTemp <> '' then
      Stream.Read(AnsiTemp[1], Stream.Size);
  finally
    Stream.Free;
  end;

  Memo1.Lines.Text := string(AnsiTemp); // hier findet ein Aufruf von MultiByteToWideChar() statt
end;

SirThornberry 7. Jan 2009 16:36

Re: Memo.Text := Ansistring? nur wie
 
das es bei move kracht liegt daran was du übergibst. Du übergibst ja sozusagen den Pointer und nicht das worauf dieser zeigt (Strings sind ja nicht die Daten an sich sondern ein Gebilde was auf Daten zeigt)

emsländer 7. Jan 2009 16:43

Re: Memo.Text := Ansistring? nur wie
 
Zitat:

Zitat von jbg

Warum nicht einfach so einlesen:
Delphi-Quellcode:
var
  Stream: TFileStream;
  AnsiTemp: AnsiString;
begin
  ...
  Stream := TFileStream.Create(odlg.FileName, fmOpenRead or fmShareDenyWrite);
  try
    SetLength(AnsiTemp, Stream.Size);
    if AnsiTemp <> '' then
      Stream.Read(AnsiTemp[1], Stream.Size);
  finally
    Stream.Free;
  end;

  Memo1.Lines.Text := string(AnsiTemp); // hier findet ein Aufruf von MultiByteToWideChar() statt
end;

Auch das funktioniert nicht und ich habe nur das erste Zeichen von über 8000 im Memo.

Gruss

EL

jbg 7. Jan 2009 16:48

Re: Memo.Text := Ansistring? nur wie
 
Zitat:

Zitat von emsländer
Auch das funktioniert nicht und ich habe nur das erste Zeichen von über 8000 im Memo.

Dann frage ich mal ganz dumm, was steht denn in der Datei (Hex-Edit) Wenn das zweite Zeichen ein #0 ist, dann ist klar, dass da nichts bei rauskommt.

emsländer 7. Jan 2009 16:53

Re: Memo.Text := Ansistring? nur wie
 
Zitat:

Zitat von jbg
Zitat:

Zitat von emsländer
Auch das funktioniert nicht und ich habe nur das erste Zeichen von über 8000 im Memo.

Dann frage ich mal ganz dumm, was steht denn in der Datei (Hex-Edit) Wenn das zweite Zeichen ein #0 ist, dann ist klar, dass da nichts bei rauskommt.

Das zweite Zeichen ist 0 - nur wenn ich die Datei wie vorher beschreiben eingelesen habe, dann war die komplett in dem AnsiString drin. Und das muss in einen normalen String rein. Das ging bei D2008 problemlos - ist ein älteres Projekt.

Gruss

EL

jbg 7. Jan 2009 17:01

Re: Memo.Text := Ansistring? nur wie
 
Zitat:

Zitat von emsländer
Das zweite Zeichen ist 0

Dann konntest du das aber auch in Delphi 2007 auch nicht in einem Memo anzeigen, denn das geht über die WinAPI und der gibt man einen PChar mit, der Nullterminiert ist.

Zitat:

nur wenn ich die Datei wie vorher beschreiben eingelesen habe, dann war die komplett in dem AnsiString drin.
Das ist sie mit meinem Code auch. Nur die Anzeige schlägt wegen dem WionAPI-PChar Problem fehl.

Wie du den Codierten Text in einen UnicodeString überträgst, musst du dir noch überlegen. Am besten dekodierst du ihn vor der Konvertierung oder du nutzt nur AnsiString für ihn.

emsländer 7. Jan 2009 17:09

Re: Memo.Text := Ansistring? nur wie
 
Zitat:

Zitat von jbg
Zitat:

Zitat von emsländer
Das zweite Zeichen ist 0

Dann konntest du das aber auch in Delphi 2007 auch nicht in einem Memo anzeigen, denn das geht über die WinAPI und der gibt man einen PChar mit, der Nullterminiert ist.

Zitat:

nur wenn ich die Datei wie vorher beschreiben eingelesen habe, dann war die komplett in dem AnsiString drin.
Das ist sie mit meinem Code auch. Nur die Anzeige schlägt wegen dem WionAPI-PChar Problem fehl.

Wie du den Codierten Text in einen UnicodeString überträgst, musst du dir noch überlegen. Am besten dekodierst du ihn vor der Konvertierung oder du nutzt nur AnsiString für ihn.

Ich widerpreche Dir an dieser Stelle. Denn die Tests, bevor ich diese Verschlüsselung in meinen Code eingebaut habe, habe ich immer mit Memos zur Kontrolle gemacht.

Wie gesagt, vorher hat mein Programm (besteht aus 45 einzelnen Units und Forms und über 100.000 Zeilen Code) so funktioniert. Diese Datei, die ich da einlese ist mittels JVCeasar verschlüsselt. Ich habe sie immer auf diese Art und Weise eingelesen und dann entschlüsselt - und voila - die in der Datei versteckten XML-Daten waren einwandfrei zu lesen. Mit D2009 klappt das jetzt so nicht mehr!

Gruss

EL

jbg 7. Jan 2009 17:19

Re: Memo.Text := Ansistring? nur wie
 
Zitat:

Zitat von emsländer
Ich widerpreche Dir an dieser Stelle.

Welchem Teil widersprichst du denn? Dem das der AnsiString die gesamten Daten aus der Datei enthält, oder dem Teil in dem ich vom PChar-Problem schreibe?

Zitat:

Diese Datei, die ich da einlese ist mittels JVCeasar verschlüsselt.
Vielleicht ist ja der Entschlüsselungs-Code defekt. (=> nicht richtig nach Unicode migriert)

emsländer 7. Jan 2009 17:23

Re: Memo.Text := Ansistring? nur wie
 
Zitat:

Zitat von jbg
Zitat:

Zitat von emsländer
Ich widerpreche Dir an dieser Stelle.

Welchem Teil widersprichst du denn? Dem das der AnsiString die gesamten Daten aus der Datei enthält, oder dem Teil in dem ich vom PChar-Problem schreibe?

Zitat:

Diese Datei, die ich da einlese ist mittels JVCeasar verschlüsselt.
Vielleicht ist ja der Entschlüsselungs-Code defekt. (=> nicht richtig nach Unicode migriert)

Ich widerspreche dem Teil, wo Du schreibst, das ich das in D2007 nicht ins Memo bekomme. Das ging definitiv!

Bis zum Enschlüsselungscode komme ich ja:

Delphi-Quellcode:
  var ansitmp : ansistring;
      stmp : string;
begin


   ansitmp := einlesen ... ;  => Hier kann ich den kompletten Inhalt im Debugger sehen.
   
   stmp := ansitmp; oder alle bisher getesteten Funktionen - nichts funktioniert. Es ist nur das erste Zeichen da.


   result := entschlüsselung; .... bisher kein Thema, aber im Moment komme ich gar nicht erst hier hin.
end;

Es muss doch "verdammtnochmal" ne Möglichkeit geben, um das Zeugs in einen String zu packen!

Gruss

EL


Gruss

EL

jbg 7. Jan 2009 17:42

Re: Memo.Text := Ansistring? nur wie
 
Zitat:

Zitat von emsländer
stmp := ansitmp; oder alle bisher getesteten Funktionen - nichts funktioniert. Es ist nur das erste Zeichen da.


result := entschlüsselung; .... bisher kein Thema, aber im Moment komme ich gar nicht erst hier hin.

Entschlüssle den Text doch vor der Umwandlung in einen UnicodeString. Bei stmp := ansitmp werden nämlich Zeichen, die größer als 127 sind, in andere Code-Points gemappt, was natürlich zu einer Fehlinterpretation führt.



Zitat:

Ich widerspreche dem Teil, wo Du schreibst, das ich das in D2007 nicht ins Memo bekomme. Das ging definitiv!
Also wenn ich " Memo1.Text := 'Hallo'#0'abc'; " in Delphi 2007 eingebe, dann steht da nur "Hallo" im Memo. Das ging also definitiv vorher auch nicht. Was aber ging, war wohl, dass die Daten nicht fehlinterpretiert wurden, weil keine Umsetzung zwischen ANSI und UTF16 stattgefunden hat.

emsländer 7. Jan 2009 17:49

Re: Memo.Text := Ansistring? nur wie
 
Zitat:

Zitat von jbg
Zitat:

Zitat von emsländer
stmp := ansitmp; oder alle bisher getesteten Funktionen - nichts funktioniert. Es ist nur das erste Zeichen da.


result := entschlüsselung; .... bisher kein Thema, aber im Moment komme ich gar nicht erst hier hin.

Entschlüssle den Text doch vor der Umwandlung in einen UnicodeString. Bei stmp := ansitmp werden nämlich Zeichen, die größer als 127 sind, in andere Code-Points gemappt, was natürlich zu einer Fehlinterpretation führt.

Wie sollte das gehen? Ich bekomme den Kram nicht einmal entschlüsselt rüber! (Was ja toll wäre)

Gruss

EL

jbg 7. Jan 2009 17:58

Re: Memo.Text := Ansistring? nur wie
 
Zitat:

Zitat von emsländer
Wie sollte das gehen? Ich bekomme den Kram nicht einmal entschlüsselt rüber! (Was ja toll wäre)

Das hieße dann aber dass du entweder defekte ANSI Daten in der Datei hast, oder du UTF16 Daten in die Datei geschrieben hast. In letzterem Fall musst du die dann natürlich als UTF16 einlesen.

Wie schreibst du denn die Daten in die Datei?

emsländer 7. Jan 2009 18:02

Re: Memo.Text := Ansistring? nur wie
 
Zitat:

Zitat von jbg
Zitat:

Zitat von emsländer
Wie sollte das gehen? Ich bekomme den Kram nicht einmal entschlüsselt rüber! (Was ja toll wäre)

Das hieße dann aber dass du entweder defekte ANSI Daten in der Datei hast, oder du UTF16 Daten in die Datei geschrieben hast. In letzterem Fall musst du die dann natürlich als UTF16 einlesen.

Wie schreibst du denn die Daten in die Datei?

Die Daten werden wie folgt geschrieben:

Delphi-Quellcode:
          try
            HttpCon.Post(sURL,strLParam,_sstream);
          except
            raise;
          end;
          sfiledata := _sstream.DataString;
          freeandnil(_sstream);
          _codiert := JvCaesarcipher.EncodeString(fddschl,sfiledata);
           fs := TFilestream.Create(sTmpFileName,fmCreate or fmShareDenyWrite);
             try
               fs.Position := 0;
               fs.Write(Pointer(_codiert)^,Length(_codiert));
             finally
               freeandnil(fs);
            end;
           close;
         end;
Gruss

EL

jbg 7. Jan 2009 18:17

Re: Memo.Text := Ansistring? nur wie
 
_codiert hast welchen Datentyp?

emsländer 7. Jan 2009 18:19

Re: Memo.Text := Ansistring? nur wie
 
Zitat:

Zitat von jbg
_codiert hast welchen Datentyp?

var _codiert : string;

Gruss

EL

jbg 7. Jan 2009 18:35

Re: Memo.Text := Ansistring? nur wie
 
Zitat:

Zitat von emsländer
var _codiert : string;

Und da haben wir den Übeltäter.

EncodeString liefert einen (kodierten) AnsiString zurück. Mit der Zuweisung an _codiert, werden nun Zeichen größer #127 falsch umgesetzt. Und beim Schreiben in die Datei wird nur die Hälfte der Daten geschrieben: Length(_codiert) <> ByteLength(_codiert)

emsländer 7. Jan 2009 18:37

Re: Memo.Text := Ansistring? nur wie
 
Zitat:

Zitat von jbg
Zitat:

Zitat von emsländer
var _codiert : string;

Und da haben wir den Übeltäter.

EncodeString liefert einen (kodierten) AnsiString zurück. Mit der Zuweisung an _codiert, werden nun Zeichen größer #127 falsch umgesetzt. Und beim Schreiben in die Datei wird nur die Hälfte der Daten geschrieben: Length(_codiert) <> ByteLength(_codiert)

Abhilfe? - ich muss vor allem die Bestandsdaten lesen können!

Gruss

EL

jbg 7. Jan 2009 18:58

Re: Memo.Text := Ansistring? nur wie
 
Zitat:

Zitat von emsländer
Abhilfe? - ich muss vor allem die Bestandsdaten lesen können!

Also alles was du mit der Delphi 2009 Version geschrieben hast, ist verstümmelt. Da kann man nichts mehr machen, da die Hälfte der Daten fehlt.
Was du mit Delphi 1-2007 geschrieben hast, kannst du komplett über AnsiString abhandeln.


Für das Schreiben reicht es aus, wenn du _codiert als AnsiString deklarierst. Du solltest aber noch prüfen, ob die Daten, die aus dem StringStream zurück kommen auch richtig sind (bei Indy bin ich mir nicht sicher, was die intern so alles mit den Daten anstellen)
Delphi-Quellcode:
uses
  JclStrings;

var
  _codiert: AnsiString;
  sfiledata: string; // = UnicodeString
begin
  ...
  _codiert := JvCaesarcipher.EncodeString(fddschl, AnsiString(sfiledata));
  StringToFile(sTmpFileName, _codiert);
end;

Beim Lesen darft du erst in einen UnicodeString konvertieren, wenn die Daten bereits entschlüsselt sind:

Delphi-Quellcode:
uses
  JclStrings;


var
  Stream: TFileStream;
  _codiert: AnsiString;
  sfiledata: string; // = UnicodeString
begin
  _codiert := FileToString(odlg.FileName);
  sfiledata := string(JvCaesarcipher.DecodeString(fddschl, _codiert));

  Memo1.Lines.Text := sfiledata;
end;

jbg 7. Jan 2009 19:00

Re: Memo.Text := Ansistring? nur wie
 
Kann es sein, dass du sämtliche String-Warnungen abgeschaltet hast? Denn der Compiler wirft überall, wo du eine implizite Konvertierung von UnicodeString nach AnsiString und andersherum machst, eine Warnung.

emsländer 7. Jan 2009 19:20

Re: Memo.Text := Ansistring? nur wie
 
Zitat:

Zitat von jbg
Zitat:

Zitat von emsländer
Abhilfe? - ich muss vor allem die Bestandsdaten lesen können!

Also alles was du mit der Delphi 2009 Version geschrieben hast, ist verstümmelt. Da kann man nichts mehr machen, da die Hälfte der Daten fehlt.
Was du mit Delphi 1-2007 geschrieben hast, kannst du komplett über AnsiString abhandeln.


Für das Schreiben reicht es aus, wenn du _codiert als AnsiString deklarierst. Du solltest aber noch prüfen, ob die Daten, die aus dem StringStream zurück kommen auch richtig sind (bei Indy bin ich mir nicht sicher, was die intern so alles mit den Daten anstellen)
Delphi-Quellcode:
uses
  JclStrings;

var
  _codiert: AnsiString;
  sfiledata: string; // = UnicodeString
begin
  ...
  _codiert := JvCaesarcipher.EncodeString(fddschl, AnsiString(sfiledata));
  StringToFile(sTmpFileName, _codiert);
end;

Beim Lesen darft du erst in einen UnicodeString konvertieren, wenn die Daten bereits entschlüsselt sind:

Delphi-Quellcode:
uses
  JclStrings;


var
  Stream: TFileStream;
  _codiert: AnsiString;
  sfiledata: string; // = UnicodeString
begin
  _codiert := FileToString(odlg.FileName);
  sfiledata := string(JvCaesarcipher.DecodeString(fddschl, _codiert));

  Memo1.Lines.Text := sfiledata;
end;

Auch das klappt leider nicht so wie es soll. Er liest zwar mehr ein als vorher, aber Source ist nicht identisch mit Destination. Kommt nur Müll bei rum.
Vor dem decodieren sieht der codierte String ganz gut aus....
Zitat:

Kann es sein, dass du sämtliche String-Warnungen abgeschaltet hast? Denn der Compiler wirft überall, wo du eine implizite Konvertierung von UnicodeString nach AnsiString und andersherum machst, eine Warnung.
nein - ich ignoriere Warnungen gern.


Gruss EL

jbg 7. Jan 2009 19:42

Re: Memo.Text := Ansistring? nur wie
 
Also folgender Code funktioniert bei mir:

Delphi-Quellcode:
var
  _codiert: AnsiString;
  sfiledata: string; // = UnicodeString
  fddschl: string;
  sTmpFileName: string;
begin
  sTmpFileName := 'C:\Testdata\Test.txt'; // *** anpassen ***

  sfiledata := '<xml>'#10'Hallo du Ärger'#10'</xml>';
  fddschl := '12';

  // write
  _codiert := JvCaesarcipher.EncodeString(fddschl, AnsiString(sfiledata));
  StringToFile(sTmpFileName, _codiert);


  // read
  _codiert := FileToString(sTmpFileName);
  sfiledata := string(JvCaesarcipher.DecodeString(fddschl, _codiert));

  Memo1.Lines.Text := sfiledata;
end;

emsländer 7. Jan 2009 19:50

Re: Memo.Text := Ansistring? nur wie
 
Zitat:

Zitat von jbg
Also folgender Code funktioniert bei mir:

Delphi-Quellcode:
var
  _codiert: AnsiString;
  sfiledata: string; // = UnicodeString
  fddschl: string;
  sTmpFileName: string;
begin
  sTmpFileName := 'C:\Testdata\Test.txt'; // *** anpassen ***

  sfiledata := '<xml>'#10'Hallo du Ärger'#10'</xml>';
  fddschl := '12';

  // write
  _codiert := JvCaesarcipher.EncodeString(fddschl, AnsiString(sfiledata));
  StringToFile(sTmpFileName, _codiert);


  // read
  _codiert := FileToString(sTmpFileName);
  sfiledata := string(JvCaesarcipher.DecodeString(fddschl, _codiert));

  Memo1.Lines.Text := sfiledata;
end;

jo - scheint wohl zu klappen --- ich hatte da noch ne Wanze drin... (der alte Code war unter dem neuen und hat das überschrieben)

Ich mache noch ein paar Tests - Tests haben funktioniert. Alles Bestens!

Vielen Dank für Deine Hilfe

Gruss

EL


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:36 Uhr.

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