![]() |
String in Array zerlegen (Markanter Punkt: ',')
Hallo,
habe einen String, der folgendermaßen aussieht: var1:='$0045CDFA,clNone,0,1,0,0' Nun möchte ich var1 in ein Array zerlegen, dass in $var2[0] '$0045CDFA' und in $var2[1] 'clNone', usw. steht ! Wie kann ich das machen ? Wie lautet der Befehl ? |
Re: String in Array zerlegen (Markanter Punkt: ',')
Zitat:
Zitat:
-> Pos(), Copy(), ggf. auch Delete() |
Code:
Und auf ruf mit:
[b]type[/b] TZeile = [b]array[/b] [b]of[/b] [b]string[/b];
[color=#000080][i]{ Zeile parsen }[/i][/color] [b]function[/b] Parse(zeile: [b]string[/b];zeilennummer:longint ):TZeile; [b]var[/b] i :longint; anzahl:longint; pos :[b]array[/b] [b]of[/b] integer; [b]begin[/b] anzahl:=0; SetLength(pos,0); SetLength(result, 0); [b]for[/b] i := 1 [b]to[/b] Length(zeile) [b]do[/b] [b]if[/b] zeile[ i ] = ';' [b]then[/b] // <-- ACHTUNG KORRIGIERT!!! [b]begin[/b] inc(anzahl); SetLength(pos, anzahl); pos[anzahl-1]:=i; SetLength(result, anzahl); [b]end[/b]; [b]for[/b] i:=0 [b]to[/b] high(result) [b]do[/b] [b]begin[/b] [b]if[/b] i=0 [b]then[/b] result[i ]:=copy(zeile,1,pos[0]-1) [b]else[/b] result[i ]:=copy(zeile,pos[i-1]+1,pos[i ]-1-pos[i-1]); // <-- ACHTUNG KORRIGIERT!!! [b]end[/b]; [color=#000080][i ]//if Length(result)=0 then Messagebox(0, '', 'Fehler', 0);[/i][/color] [b]end[/b];
Code:
Auf die einzelnen Elemente kannst du dann mit den Index zugreifen. Das erste Element bekommst du dann mit Zeile[0].
[b]var[/b]
Zeile : TZeile; [b]begin[/b] Zeile := Parse(s, 0); |
Habe es nun so gemacht:
Code:
Aber er sagt:
type TZeile = array of string;
. . . //Deine Funktion . . . function TMain.Intialize_Highlight(): Bool; var ini: TIniFile; php_comment, php_identifier, php_invalidsymbol, php_key, php_number, php_space, php_string, php_symbol, php_variable: TZeile; tmp_style: TFontStyle; begin ini := TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'highlight.cfg'); try php_comment := Parse(ini.ReadString('PHP','Comment','$0045CDFA,clNone,0,1,0,0'), 0); { Zeile 180 }PHPhigh.CommentAttri.Foreground := IntToStr(php_comment[0]); PHPhigh.CommentAttri.Background := IntToStr(php_comment[1]); if IntToStr(php_comment[2]) = 1 then PHPhigh.CommentAttri.Style := fsBold; if IntToStr(php_comment[3]) = 1 then PHPhigh.CommentAttri.Style := fsItalic; if IntToStr(php_comment[4]) = 1 then PHPhigh.CommentAttri.Style := fsUnderline; if IntToStr(php_comment[5]) = 1 then PHPhigh.CommentAttri.Style := fsStrikeOut; finally ini.Free; end; end; [Fehler] main_unit.pas(180): Es gibt keine überladene Version von 'IntToStr', die man mit diesen Argumenten aufrufen kann |
php_comment[2]
Das ist doch schon ein String. Kuck dir doch mal die Typdeklarartion von TZeile an: array of String. |
Re: String in Array zerlegen (Markanter Punkt: ',')
Zitat:
Zitat:
|
ACHTUNG, ACHTUNG der Coderformatierer hat ein paar [*i*]'s geschluckt. Ich habe es korrigiert. Bitte überprüf noch mal deinen Code. Danke
|
Moin Luckie,
ich hab' jetzt mal den Code aus dem Posting genommen, alle Blanks vor bzw. hinter den eckigen Klammern entfernt und den Formatierer laufen lassen. Kein Fehler feststellbar. :shock: |
OK, Alles nochmal:
Code:
Er sagt mir:
type TZeile = array of string;
. public { Public-Deklarationen } function Intialize_Highlight(): Bool; function Parse(zeile: string;zeilennummer:longint ):TZeile; . function TMain.Parse(zeile: string;zeilennummer:longint ):TZeile; var i :longint; anzahl:longint; pos :array of integer; begin anzahl:=0; SetLength(pos,0); SetLength(result, 0); for i := 1 to Length(zeile) do if zeile[ i ] = ';' then // <-- ACHTUNG KORRIGIERT!!! begin inc(anzahl); SetLength(pos, anzahl); pos[anzahl-1]:=i; SetLength(result, anzahl); end; for i:=0 to high(result) do begin if i=0 then result[i ]:=copy(zeile,1,pos[0]-1) else result[i ]:=copy(zeile,pos[i-1]+1,pos-1-pos[i-1]); // <-- ACHTUNG KORRIGIERT!!! end; //if Length(result)=0 then Messagebox(0, '', 'Fehler', 0); end; function TMain.Intialize_Highlight(): Bool; var ini: TIniFile; php_comment, php_identifier, php_invalidsymbol, php_key, php_number, php_space, php_string, php_symbol, php_variable: TZeile; tmp_style: TZeile; begin ini := TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'highlight.cfg'); try php_comment := Parse(ini.ReadString('PHP','Comment','$0045CDFA,clNone,0,1,0,0'), 0); PHPhigh.CommentAttri.Foreground := IntToStr(php_comment[0]); PHPhigh.CommentAttri.Background := IntToStr(php_comment[1]); if IntToStr(php_comment[2]) = 1 then PHPhigh.CommentAttri.Style := fsBold; if IntToStr(php_comment[3]) = 1 then PHPhigh.CommentAttri.Style := fsItalic; if IntToStr(php_comment[4]) = 1 then PHPhigh.CommentAttri.Style := fsUnderline; if IntToStr(php_comment[5]) = 1 then PHPhigh.CommentAttri.Style := fsStrikeOut; finally ini.Free; end; end; [Fehler] main_unit.pas(157): Operator ist auf diesen Operandentyp nicht anwendbar Die Zeile:
Code:
Wo liegt der Fehler ?
result[i ]:=copy(zeile,pos[i-1]+1,pos-1-pos[i-1]);
Kann ich das ganze nicht verkürzen ? Ich müsste das ganze sonst noch mit PHPhigh.IdentifierAttri.... und noch weiteren 40 Objekten machen und das wäre sehr viel Code ! Kann man das alles nicht in eine Funktion zusammenfassen, an die ich nur noch z.B. "PHPHigh.CommentAttri" übergeben muss ? |
Also bei mir tut es die Funktion jedes mal. Keinen Plan, was du da gemacht hast. :?
|
Moin Rebugger,
Du hast pos als array of integer deklariert, dann aber ohne Index benutzt
Code:
wobei ich etwas unglücklich finde einen Funktionsnamen (pos) als Variablennamen zu benutzten. ;-)
result[i ]:=copy(zeile,pos[i-1]+1,[color=red]pos[/color]-1-pos[i-1]);
|
Ja, is klar...
Blick nur nich durch, was daran geändert werden muss (welcher array wert dort hineingehört) Habe nun eine extra funktion für den aufruf von parse() geschrieben:
Code:
Jetzt müsste nur noch der Fehler in der Funktion Parse() gefixed werden.
function TMain.Intialize_Highlight(Highlight: TSynHighlighterAttributes; Section: String; Part: String; Standard: String): Bool;
var ini: TIniFile; tmp_style: TZeile; begin ini := TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'highlight.cfg'); try tmp_style := Parse(ini.ReadString(Section,Part,Standard), 0); Highlight.Foreground := StrToInt(tmp_style[0]); Highlight.Background := StrToInt(tmp_style[1]); if StrToInt(tmp_style[2]) = 1 then Highlight.Style := [fsBold]; if StrToInt(tmp_style[3]) = 1 then Highlight.Style := [fsItalic]; if StrToInt(tmp_style[4]) = 1 then Highlight.Style := [fsUnderline]; if StrToInt(tmp_style[5]) = 1 then Highlight.Style := [fsStrikeOut]; finally ini.Free; end; result := TRUE; end; Weiß aber net, was da reingehört ! |
In der zeile:
Code:
war noch ein Fehler drin. Ich habe ihn noch mal korrigiert.
result[i ]:=copy(zeile,pos[i-1]+1,pos[i ]-1-pos[i-1]);
|
Hm, trotzdem sagt er beim Start meines Programmes:
"Zugriffsverletzung auf Adresse 004A8725 in Modul 'project1.php'. Lesen von Adresse 00000000." |
Dann hast du irgendwo eine ungültige Zeile drin. Bei dem Parser ist das Trennzeichen ein ";" du hast aber ein ",". Also in der Parse-Funktion anpassen.
|
Hm, dann sagt er mir beim Aufruf "clNone ist kein gültiger Integerwert"
Das liegt an pos: array of integer; Aber dieser lange String Comment=$0045CDFA,clNone,0,1,0,0 Kann ja Buchstaben und Zahlen enthalten ! |
Kann es sein, dass dein Fehler irgendwo hier
Code:
liegt?
if IntToStr(php_comment[2]) = 1 then
PHPhigh.CommentAttri.Style := fsBold; if IntToStr(php_comment[3]) = 1 then PHPhigh.CommentAttri.Style := fsItalic; if IntToStr(php_comment[4]) = 1 then PHPhigh.CommentAttri.Style := fsUnderline; if IntToStr(php_comment[5]) = 1 then PHPhigh.CommentAttri.Style := fsStrikeOut; |
Jo, hab das jetzt korrigiert !
Wenn ich in der Funktion Parse()
Code:
Kommt nurnoch dieser Fehler:
if zeile[ i ] = ',' then
"clNone ist kein gültiger Integerwert" Das liegt an pos: array of integer; Aber dieser String $0045CDFA,clNone,0,1,0,0 kann ja Buchstaben und Zahlen enthalten |
Halt, Stopp !
Kommando zurück ! Fehler-Stelle gefunden:
Code:
Lag an meiner Funktion !
Highlight.Foreground := StrToInt(tmp_style[0]);
Highlight.Background := StrToInt(tmp_style[1]); Da ja hier bei tmp_style[1] "clNone" drin steht und nicht zu Integer umgewandelt werden kann ! Wie kann ich sonst von String in TColor umwandeln ? |
Moin Rebugger,
da auch dynamische Arrays wieder freigegeben werden müssen, hätte ich da noch zwei Vorschläge. 1. Mit Luckies Parse / TZeile
Code:
2. Mit einer TStringList statt array of string und StringReplace statt Parse
[b]function[/b] TMain.Intialize_Highlight(Highlight: TSynHighlighterAttributes; Section: [b]String[/b]; Part: [b]String[/b]; Standard: [b]String[/b]): Bool;
[b]var[/b] ini: TIniFile; tmp_style: TZeile; [b]begin[/b] ini := TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'highlight.cfg'); [b]try[/b] tmp_style := Parse(ini.ReadString(Section,Part,Standard), 0); [b]try[/b] Highlight.Foreground := StrToInt(tmp_style[0]); Highlight.Background := StrToInt(tmp_style[1]); [b]if[/b] StrToInt(tmp_style[2]) = 1 [b]then[/b] Highlight.Style := [fsBold]; [b]if[/b] StrToInt(tmp_style[3]) = 1 [b]then[/b] Highlight.Style := [fsItalic]; [b]if[/b] StrToInt(tmp_style[4]) = 1 [b]then[/b] Highlight.Style := [fsUnderline]; [b]if[/b] StrToInt(tmp_style[5]) = 1 [b]then[/b] Highlight.Style := [fsStrikeOut]; [b]finally[/b] finalize(tmp_style); FreeAndNil(tmp_style); [b]end[/b]; [b]finally[/b] ini.Free; [b]end[/b]; result := TRUE; [b]end[/b];
Code:
[b]function[/b] TMain.Intialize_Highlight(Highlight: TSynHighlighterAttributes; Section: [b]String[/b]; Part: [b]String[/b]; Standard: [b]String[/b]): Bool;
[b]var[/b] ini: TIniFile; tmp_style: TStringList; [b]begin[/b] ini := TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'highlight.cfg'); [b]try[/b] tmp_style := TStringList.Create; [b]try[/b] tmp_style := StringReplace(ini.ReadString(Section,Part,Standard),',',#13#10,[rfReplaceAll]); Highlight.Foreground := StrToInt(tmp_style[0]); Highlight.Background := StrToInt(tmp_style[1]); [b]if[/b] StrToInt(tmp_style[2]) = 1 [b]then[/b] Highlight.Style := [fsBold]; [b]if[/b] StrToInt(tmp_style[3]) = 1 [b]then[/b] Highlight.Style := [fsItalic]; [b]if[/b] StrToInt(tmp_style[4]) = 1 [b]then[/b] Highlight.Style := [fsUnderline]; [b]if[/b] StrToInt(tmp_style[5]) = 1 [b]then[/b] Highlight.Style := [fsStrikeOut]; [b]finally[/b] FreeAndNil(tmp_style); [b]end[/b]; [b]finally[/b] ini.Free; [b]end[/b]; result := TRUE; [b]end[/b]; |
Moin Rebugger,
Zitat:
Mit StringToColor :mrgreen: |
Moin Rebugger,
was mir gerade aufgefallen ist: Die Style Attribute ergänzen sich nicht, sondern das zuletzt gefundene ersetzt bereits gesetzte. Statt Highlight.Style := [fsItalic]; müsste es also Highlight.Style := Highlight.Style + [fsItalic]; heissen. (bei den folgenden Attributen analog versteht sich). |
Wow, Christian !
OK, habe deine 2. Methode mit der Stringlist genommen ! Einizger Fehler:
Code:
[Fehler] main_unit.pas(197): Inkompatible Typen: 'TStringList' und 'String'
tmp_style := StringReplace(ini.ReadString(Section,Part,Standard),',',#13#10,[rfReplaceAll]);
|
Hm, ok, Problem auch wieder gelöst !
Mein aktueller Code:
Code:
Jetzt sagt er beim Aufruf:
function TMain.Intialize_Highlight(Highlight: TSynHighlighterAttributes; Section: String; Part: String; Standard: String): Bool;
var ini: TIniFile; tmp_style: TStringList; begin ini := TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'highlight.cfg'); try tmp_style := TStringList.Create; try tmp_style.Add(StringReplace(ini.ReadString(Section,Part,Standard),',',#13#10,[rfReplaceAll])); Highlight.Foreground := StringToColor(tmp_style[0]); Highlight.Background := StringToColor(tmp_style[1]); if tmp_style[2] = '1' then Highlight.Style := Highlight.Style + [fsBold]; if tmp_style[3] = '1' then Highlight.Style := Highlight.Style + [fsItalic]; if tmp_style[4] = '1' then Highlight.Style := Highlight.Style + [fsUnderline]; if tmp_style[5] = '1' then Highlight.Style := Highlight.Style + [fsStrikeOut]; finally FreeAndNil(tmp_style); end; finally ini.Free; end; result := TRUE; end; [b]'$0045CDFA clNone 0 1 0 0' ist kein gültiger Integerwert8/b] |
Hm, ok, Problem auch wieder gelöst !
Mein aktueller Code:
Code:
Jetzt sagt er beim Aufruf:
function TMain.Intialize_Highlight(Highlight: TSynHighlighterAttributes; Section: String; Part: String; Standard: String): Bool;
var ini: TIniFile; tmp_style: TStringList; begin ini := TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'highlight.cfg'); try tmp_style := TStringList.Create; try tmp_style.Add(StringReplace(ini.ReadString(Section,Part,Standard),',',#13#10,[rfReplaceAll])); Highlight.Foreground := StringToColor(tmp_style[0]); Highlight.Background := StringToColor(tmp_style[1]); if tmp_style[2] = '1' then Highlight.Style := Highlight.Style + [fsBold]; if tmp_style[3] = '1' then Highlight.Style := Highlight.Style + [fsItalic]; if tmp_style[4] = '1' then Highlight.Style := Highlight.Style + [fsUnderline]; if tmp_style[5] = '1' then Highlight.Style := Highlight.Style + [fsStrikeOut]; finally FreeAndNil(tmp_style); end; finally ini.Free; end; result := TRUE; end; '$0045CDFA clNone 0 1 0 0' ist kein gültiger Integerwert |
Moin Rebugger,
war ein blöder Fehler von mir (kommt davon wenn man's nicht ausprobiert :oops: ) Es muss eigentlich heissen: tmp_style.text := StringReplace(.... Dann sollte der beschriebene Fehler auch weg sein. Wenn Du die Zeile mit Add hinzufügst, werden die Steuerzeichen (#13#10) nicht als Zeilenumbruch gewertet, sondern mit in den ersten String der Liste übernommen. Weist Du hingegen der Eigenschaft Text einen String zu, der die Zeilenumbruchzeichen enthält, dröselt Delphi das zu einzelnen Zeilen auf. Der Nachteil aller komfortablen Stringfunktionen / -Klassen (z.B. eben StringReplace, TStringList) ist allerdings die oft schlechte Performance. Wenn diese oft genutzt werden (z.B. in Schleifen) wirkt sich das meist stark auf die Geschwindigkeit aus. |
Und deswegen hatte ich ja gedacht, Chris, du schiebst den komma-separierten String direkt an die Eigenschaft "CommaText". Dann hättest du dir den "StringReplace"-Kram sparen können.
Code:
tmp_style.CommaText := ini.ReadString(Section,Part,Standard);
|
Danke euch beiden (Christian und Mathias) !
Habe nun alles richtig und mein Programm läuft perfekt ! Vielen Dank nochmal ! |
Moin Mathias,
stimmt, hast Du auch wieder wahr :mrgreen: CommaText hatte ich bislang nie verwendet. Wieder was gelernt. |
Zitat:
Chris |
Zitat:
|
Zitat:
|
Zitat:
|
hehe, musst mich net für doof halten... hatte nur die meldung falsch abgeschrieben ! das is natürlich .exe ! das mit .php war nur reine gewohnheit !
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:17 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz