Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi C-Like Formatfunktion (https://www.delphipraxis.net/111723-c-like-formatfunktion.html)

Bernhard Geyer 8. Apr 2008 12:44


C-Like Formatfunktion
 
Gibt es eine fertige (performante) Funktion um C-Like (\n -> CRLF) Ersetzungen in einem String vornehmen zu können?

Muetze1 8. Apr 2008 12:46

Re: C-Like Formatfunktion
 
Zitat:

Zitat von Bernhard Geyer
Gibt es eine fertige (performante) Funktion um C-Like (\n -> CRLF) Ersetzungen in einem String vornehmen zu können?

Ich kapier die Frage nicht, da der C Compiler sowas direkt in das Steuerzeichen umwandelt und so wird die Zeichenkette doch auch in der EXE abgelegt. Da wird doch nichts irgendwie zur Laufzeit umgewandelt - oder verstehe ich da nun was falsch?

Oder willst du nur eine Liste haben mit den möglichen Steuerzeichen? So nach dem Motto: \n \r \t \b \\ \0 etc?

Bernhard Geyer 8. Apr 2008 12:55

Re: C-Like Formatfunktion
 
Ich habe einen String aus einer Textdatei welchen ich entsprechend überarbeiten will.
Die Textdatei ist CSV-Datei die ich Tabelarisch einlesen will und hier will ich jetzt auch in einer Zelle mehrzeilige Text einlesen können wenn diese bei den entsprechenden Zellen mit "\n" gekennzeichnet sind. Nur CR bzw. LF kann ich nicht verwenden da ich u.U. die Datei von einem MAC bzw. Unix/Linux-System bekomme. Bisher musste in einem solchen Fall auf Excel zurückgegriffen werden.

Ghostwalker 8. Apr 2008 15:01

Re: C-Like Formatfunktion
 
Also brauchst du, wenn ich das richtig kapiere, eine Funktion die dir "\n" -> CRLF (beim lesen) wandelt, bzw. umgekehrt (beim schreiben in die Datei) ?

Am einfachsten geht das mit StringReplace...

Bernhard Geyer 8. Apr 2008 22:09

Re: C-Like Formatfunktion
 
Zitat:

Zitat von Ghostwalker
Am einfachsten geht das mit StringReplace...

String-Replace nicht ganz da ich ja "\" als "\\" Escaped vorhanden sein kann. Ich hab mir zwar jetzt schon was zusammengestrickt (mit LastPos langsam nach "vorne" gearbeitet und bei vorkommen von "\n" geschaut ob nicht davor noch ein "\" kommt und damit "\\" -> "\" anstatt "\n" -> CRLF durchgeführt würd) aber ob das wirklich das logisch die beste Lösung ist bzw. nicht noch schneller gelößst werden kann ...

Muetze1 8. Apr 2008 22:51

Re: C-Like Formatfunktion
 
Ich verstehe dein Problem bei StringReplace nicht. Du sollst ja nicht ein einzelnes \ ersetzen sondern direkt \\. Also so (Pseudocode)

Code:
  Out := StringReplace(In, '\n', cLineBreak, [rfIgnoreCase, rfReplaceAll]);
  Out := StringReplace(Out, '\r', #13, [rfIgnoreCase, rfReplaceAll]);
  Out := StringReplace(Out, '\b', #8, [rfIgnoreCase, rfReplaceAll]);
  Out := StringReplace(Out, '\0', #0, [rfIgnoreCase, rfReplaceAll]);
  Out := StringReplace(Out, '\t', #9, [rfIgnoreCase, rfReplaceAll]);
  Out := StringReplace(Out, '\\', '\', [rfIgnoreCase, rfReplaceAll]);

Bernhard Geyer 8. Apr 2008 22:56

Re: C-Like Formatfunktion
 
Und was ist mit folgendem Fall:

"\\n" welcher z.B. in "C:\\Verzeichnis\\n1\\Sub1\\..." vorkommt?

Dax 8. Apr 2008 22:56

Re: C-Like Formatfunktion
 
Delphi-Quellcode:
function UnescapeC(const s: string): string;
var i, cidx: integer; inEscape: Boolean;

  procedure SpecialToChar(c: char): Char;
  begin
    case c of
      '0': result := #0;
      'a': result := #7;
      'b': result := #8;
      't': result := #9;
      'n': result := #10;
      'v': result := #11;
      'f': result := #12;
      'r': result := #13;
      'e': result := #27;
    end;
  end;

begin
  if not assigned(s) or Length(s) < 2 then
  begin
    result := s;
    exit;
  end;
  cidx := 1;
  inEscape := false;
  SetLength(result, Length(s));
  for i := 1 to Length(s) do
  begin
    case s[i] of
      '\': begin
             if inEscape then
             begin
               result[cidx] := '\';
               Inc(cidx);
             end;
             inEscape := not inEscape;
           end;
      '0', 'a', 'b', 't', 'n', 'v', 'f', 'r', 'e':
        begin
          if inEscape then
            result[cidx] := SpecialToChar(s[i]);
          else
            result[cidx] := s[i];
          Inc(cidx);
          inEscape := false;
        end;
    else
      result[cidx] := s[i];
      Inc(cidx);
    end;
  end;
  SetLength(result, cidx-1);
end;
Habs nicht getestet, aber das sollte eigentlich funktionieren...

Muetze1 8. Apr 2008 23:52

Re: C-Like Formatfunktion
 
Zitat:

Zitat von Bernhard Geyer
Und was ist mit folgendem Fall:

"\\n" welcher z.B. in "C:\\Verzeichnis\\n1\\Sub1\\..." vorkommt?

Ich hatte den Fall schon zuvor ähnlich überlegt um festzustellen ob die \\ Ersetzung als erstes oder letztes kommen muss. Du hast aber natürlich vollkommen Recht. StringReplace() ist ungeeignet, da es den String mit jedem Aufruf erneut von vorne durchläuft. Die Ersetzungen müssten aber linear geschehen in einem Durchlauf.

holliesoft 9. Apr 2008 08:03

Re: C-Like Formatfunktion
 
Zitat:

Zitat von Bernhard Geyer
Gibt es eine fertige (performante) Funktion um C-Like (\n -> CRLF) Ersetzungen in einem String vornehmen zu können?

Hi Bernhard,

In der JCL gibt es die Funktion StrEscapedToString (Unit JclAnsiStrings).

Gruß
Patrick


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:08 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