Autor Beitrag
MagicRain
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 154

WinXp, Win8, iOS
Delphi 7, Lazarus Pascal, Delphi 10.2 Starter, NetBeans Java
BeitragVerfasst: Do 25.06.09 19:19 
Hallo ich möchte folgendes mit einem langen String machen....

ausblenden Quelltext
1:
2:
3:
4:
5:
C92917D2E4D98789EE51928EECA075E8K3NDI45JKS90OMLJD56JLSDJ7LSK6DK .........

wird zu:

C929-17D2-E4D9-8789-EE51 ......................


Habe es mal so versucht aber das kalppt nicht so ganz wie ich es möchte :(
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm1.Button1Click(Sender: TObject);
var
a,b:String;
begin
  a :=  Edit1.Text;
  a[5] :='-';
  Edit2.Text := a;
end;


Wäre nett wenn mir jemand da irgendwie helfen kann?!?!

MfG


Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Do 25.06.2009 um 20:00
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Do 25.06.09 19:29 
Etwa so in der Art:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
var orginal, neu: String;
begin
i := 1;
j := 1;
while i <= length(orginal) do
begin
neu[j] := orginal[i];

inc(j);

  if (i mod 5 = 0and (i <> length(orginal)) then
  begin
    neu[j] := '-';
    inc(j);
  end;

inc(i);
end;
elundril
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3747
Erhaltene Danke: 123

Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
BeitragVerfasst: Do 25.06.09 19:33 
is zwar jetzt n bissal code mit pseudocode vermischt aber ich denke es wird dir helfen:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TForm1.Button1Click(Sender: TObject);
var orginal, neu: String;
begin
  original := Edit1.Text;
  i := 1;
  j := 1;
  während i+4 <= länge(orginal) do begin
    kopiere von der stelle i bis i+4 den text aus original in neu;
    füge am ende von neu ein '-' an;
    inkrementiere i um 4;
  end;
end;

_________________
This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
MagicRain Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 154

WinXp, Win8, iOS
Delphi 7, Lazarus Pascal, Delphi 10.2 Starter, NetBeans Java
BeitragVerfasst: Do 25.06.09 19:49 
Oh man danke euch :)

MfG
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 25.06.09 19:53 
Oder gleich in eine Funktion gepackt:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
function InsertGivenChar(const Src: string; InsChr: char; InsertAfter: integer): string;
var i,j: integer;
begin
  SetLength(Result,Length(Src) + Length(Src) div InsertAfter);
  i := 1;
  j := 1;
  while i <= Length(Src) do
    begin
      Result[j] := Src[i];
      inc(j);
      if ((i mod InsertAfter) = 0and (i < Length(Src)) then
        begin
          Result[j] := InsChr;
          inc(j);
        end;
      inc(i);
    end;
end;


[edit] Denkfehler korrigiert, das kommt davon, wenn man direkt im Editor tippt. [/edit]


Zuletzt bearbeitet von DeddyH am Fr 26.06.09 20:03, insgesamt 2-mal bearbeitet
elundril
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3747
Erhaltene Danke: 123

Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
BeitragVerfasst: Do 25.06.09 22:07 
darf ich fragen warum ihr beide die Copyfunktion von Delphi so verschmäht?

lg elundril

(Die Befehlssyntax ist folgende: anyString := Copy(anotherString, Index, Count);)

_________________
This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
Lannes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: Do 25.06.09 22:57 
Hallo,

nicht die Copyfunktion wird verschmäht, sondern die durch Copy erforderlich werdenden Stringverkettungen.

_________________
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 26.06.09 08:19 
Wenn es um Geschwindigkeit geht:
Da sollte man dann erstens keine while-Schleife nehmen, bei der in jedem Durchlauf Length aufgerufen wird und zweitens nicht auf Strings indiziert zugreifen, da bei diesem zeichenweisen Zugriff jedes Mal der Referenzzähler überprüft wird. ;-)

@user profile iconDeddyH: Deine Methode verschluckt das letzte Zeichen, nämlich das mit dem Index Length(Src), denn da brichst du schon ab, stattdessen steht da ein zufälliges Zeichen drin. ;-)

Wenn die Stringlänge ein Vielfaches der Länge der Einzelteile, hier also 4, ist, dann geht es auch so:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
function InsertHyphens4A(const AText: AnsiString): AnsiString;
var
  i, TextLen: Integer;
  Src, Dst: PAnsiChar;
begin
  TextLen := Length(AText);
  SetString(Result, nil, TextLen + Pred(TextLen div 4));
  Src := PChar(AText);
  Dst := PChar(Result);
  for i := 1 to Pred(TextLen div 4do
  begin
    PLongWord(Dst)^ := PLongWord(Src)^;
    Inc(Src, 4);
    Inc(Dst, 4);
    Dst^ := '-';
    Inc(Dst);
  end;
  PLongWord(Dst)^ := PLongWord(Src)^;
end;
Oder allgemeiner und auch für Unicode in D2009, dafür langsamer:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
function InsertHyphens(const AText: string; AChars: Integer): string;
var
  i, TextLen: Integer;
  Src, Dst: PChar;
begin
  TextLen := Length(AText);
  SetString(Result, nil, TextLen + Pred(TextLen div AChars));
  Src := PChar(AText);
  Dst := PChar(Result);
  for i := 1 to Pred(TextLen div AChars) do
  begin
    CopyMemory(Dst, Src, AChars * SizeOf(Char));
    Inc(Src, AChars);
    Inc(Dst, AChars);
    Dst^ := '-';
    Inc(Dst);
  end;
  CopyMemory(Dst, Src, AChars * SizeOf(Char));
end;
MagicRain Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 154

WinXp, Win8, iOS
Delphi 7, Lazarus Pascal, Delphi 10.2 Starter, NetBeans Java
BeitragVerfasst: Fr 26.06.09 12:25 
So danke euch für die ganzen Beiträge richtig klasse aber ich habe die Lösung dann doch gefunden viel einfacher!

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
  // Final_Format_ ( '-' ).....
  Insert('-',STRING1,5);
  Insert('-',STRING1,10);
  Insert('-',STRING1,15);
  Insert('-',STRING1,20);

  // String__CUT!
  SetLength(STRING1, 24);


MfG
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 26.06.09 12:28 
Klar, das passt für diesen Fall, aber ist nicht variabel, falls man das nochmal braucht ;)
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 26.06.09 12:36 
Und ist natürlich sehr viel langsamer, also nur geeignet, wenns nur einmal oder so ausgeführt wird. In einer Schleife wäre sowas kaum sinnvoll. :D
MagicRain Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 154

WinXp, Win8, iOS
Delphi 7, Lazarus Pascal, Delphi 10.2 Starter, NetBeans Java
BeitragVerfasst: Fr 26.06.09 13:01 
Ja da muss ich euch rechtgeben :) nun habe ich ja viele lösungen danke :)

MfG
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 26.06.09 13:10 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
Function InsertDashes(S: String): String;
var
    X: Integer;
    SP,DP: PChar;
Begin
    SetLength(Result, Length(S) + Length(S) div 4);
    SP := @S[1];
    DP := @Result[1];
    For X := 1 to Length(S) do
    Begin
        DP^ := SP^;
        Inc(SP);
        Inc(DP);
        If (X and 3) = 0 then
        Begin
            DP^ := '-';
            Inc(DP);
        end;
    end;
end;


Die Übersetzung nach ASM überlasse ich dem geneigten Leser ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Fr 26.06.09 19:10 
Wartbarkeit, Lesbarkeit, Robustheit, Portierbarkeit gegen unnütze Performance macht hier keinen Sinn. For-Schleife mit Insert o.ä. ist dagegen einfach zu verstehen, praktisch selbsterklärend und macht am wenigsten Annahmen über den Aufbau von Strings.

Wartbarkeit:
Wenn mit Assembler oder Pointern gearbeitet wird: Ist schwieriger zu debuggen, verstehen und erweitern (vor allem von anderen)

Lesbarkeit:
Assembler praktisch unlesbar. Mit Pointern ist es etwas besser aber nicht besonders elegant.

Robustheit:
Schnell mal einen Bug programmiert durch undurchdachter Zugriff über Pointer:
InsertDashes: Macht einen ungültigen Zugriff auf [1], wenn der Eingabestring leer ist.
InsertHyphens4A/InsertHyphens: Schreibt auf PChar(''), wenn der Eingabestring leer ist.

Portierbarkeit:
Assembler ist überhaupt nicht portabel. Falls mit Pointern und/oder CopyMemory gearbeitet wurde: Vorsicht geboten bei Transition von String zu UnicodeString -> Code macht möglicherweise Annahmen über die Struktur von String.

Fazit:
Die Prozedur, die oben keine Pointerarithmetik verwendet ist InsertGivenChar. Die einzige Prozedur, die hier sicher gegen Zugriffsverletzung ist. Allerdings durch die Verwendung von mehreren Indizes etwas unübersichtlich, und enthält einen Denkfehler: Die Prozedur funktioniert nicht wie gewünscht, wenn Length(Src) mod InsertAfter = 0 bei Length(Src)>0
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 26.06.09 20:03 
Stimmt, hab es oben verbessert.
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Fr 26.06.09 21:32 
Oh..Oh..Oderso (Kurz und Knapp):
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
Function UnterteileString (Const aString : string; aTeilerZeichen : Char; aAbstand : Integer) : String;
Var
  i : Integer;

Begin
  i := aAbstand+1;
  Result := aString;
  While i <= Length (Result) do begin
    Insert (aTeilerZeichen,Result,i);
    inc (i, aAbstand+1);
  End
End;

_________________
Na denn, dann. Bis dann, denn.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 26.06.09 21:37 
user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Wartbarkeit, Lesbarkeit, Robustheit, Portierbarkeit gegen unnütze Performance macht hier keinen Sinn. For-Schleife mit Insert o.ä. ist dagegen einfach zu verstehen, praktisch selbsterklärend und macht am wenigsten Annahmen über den Aufbau von Strings.

For-Schleife mit Insert ist dagegen: ultra lahmarschig, strapaziert den Memory Manager unnötig, ist einfach unelegant!

user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Wartbarkeit:
Wenn mit Assembler oder Pointern gearbeitet wird: Ist schwieriger zu debuggen, verstehen und erweitern (vor allem von anderen)

Dafür gibt es Kommentare ... sofern diese nötig sein sollte :mrgreen:

user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Lesbarkeit:
Assembler praktisch unlesbar. Mit Pointern ist es etwas besser aber nicht besonders elegant.

ASM ja, Pointer sind dagegen ein warer Genuss. Je kürzer die Anweisung, desto klarer wird sie.

user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Robustheit:
Schnell mal einen Bug programmiert durch undurchdachter Zugriff über Pointer:
InsertDashes: Macht einen ungültigen Zugriff auf [1], wenn der Eingabestring leer ist.

Falsch: Wenn Input-String leer ist, wird zwar [1] als Adresse aufgelöst, jedoch nie zugegriffen.

user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
InsertHyphens4A/InsertHyphens: Schreibt auf PChar(''), wenn der Eingabestring leer ist.

Portierbarkeit:
Assembler ist überhaupt nicht portabel. Falls mit Pointern und/oder CopyMemory gearbeitet wurde: Vorsicht geboten bei Transition von String zu UnicodeString -> Code macht möglicherweise Annahmen über die Struktur von String.

Meine Pointer-Version IST Portabel ;-)

user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Fazit:
Die Prozedur, die oben keine Pointerarithmetik verwendet ist InsertGivenChar. Die einzige Prozedur, die hier sicher gegen Zugriffsverletzung ist.

Jain ... InsertDashes ist auch sicher gegen Zugriffsverletzungen, trotz dem Pointer-Arithmetik verwendet wird. Was jedoch bei meiner Routine wichtig ist, ist die Tatsache, dass man genau wissen sollte, was jeder Befehl tut. Ist also nichts, was man unkonzentriert schreiben sollte ...

user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
Allerdings durch die Verwendung von mehreren Indizes etwas unübersichtlich, und enthält einen Denkfehler: Die Prozedur funktioniert nicht wie gewünscht, wenn Length(Src) mod InsertAfter = 0 bei Length(Src)>0

Und genau diese doppelten Index-Berechnungen machen InsertGivenChar nicht optimal, da ständig Sachen doppelt und dreifach berechnet werden.

Kommt halt immer drauf an, was man speziell will.

Geht Kürzer:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
Function UnterteileStringShorterSource (Const S : string; C : Char; A : Integer) : String;
Var
  i : Integer;
Begin
  Result := S;
  i := (Length(S) div A) * A + 1;
  While i > 1 do begin
    Insert (C, Result, i);
    Dec(i, A);
  End;
End;

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Oreaden
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 16



BeitragVerfasst: Fr 26.06.09 23:04 
juten Morgen,

sehe ich das richtig, 'n Wettbewerb? Da will ich doch auch zwei Zeilen in den Ring werfen

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
(***********************************************************)
(*** Aufruf: InsStr(a, 3, '-');                          ***)
(***********************************************************)
procedure InsStr(Var aStr: stringAt: integer; Chr: char);
var
 LengthIdx,RunIdx   : integer;
 TmpStr   : string;
 SourceChar, DestinationChar: PChar;
begin
 LengthIdx := length(aStr);
 if (LengthIdx = 0or (LengthIdx < atthen exit;
 TmpStr := aStr;
 setlength(aStr, LengthIdx + LengthIdx div at);
 SourceChar := @TmpStr[at];
 DestinationChar := @aStr[at];
 RunIdx  := at;
 while RunIdx < LengthIdx do
 begin
  if RunIdx mod at = 0 then
  begin
   inc(DestinationChar);
   DestinationChar^ := chr;
  end;
  inc(RunIdx);
  inc(SourceChar);
  inc(DestinationChar);
  DestinationChar^:= SourceChar^;
 end;
end;


vielleicht gefällts

Oreaden
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Fr 26.06.09 23:16 
@BenBE: Ich werde nicht versuchen, dich zu ändern ;) Du darfst gerne deine eigene Meinung behalten. Ich bleibe bei meiner Meinung.

"@S[1]": Okay, gibt vielleicht keine Zugriffsverletzung, aber führt dazu, dass du keine Range-Checks mehr verwenden darfst. Kann man ja ausschalten, würdest du jetzt sagen. Klar, es gibt für alles eine Lösung. Aber in meiner täglichen Arbeit merke ich einfach, dass solche Kleinigkeiten mit der Zeit mühsam sind. Wenn die Hälfte nicht da steht oder eine Menge Annahmen im Code stecken, die nur der Originalautor kennt, dann knallt's halt öfters mal und man muss rumwerkeln, bis es endlich läuft. Im schlimmsten Fall muss ich eine Änderung in Fremd-Code machen, und beim nächsten Update darf ich wieder nachprüfen, ob der Fehler in zwischen schon gefixt ist, oder ob ich die Änderung wieder machen muss.

Ich will in erster Linie ein Programm, eine Prozedur, eine Komponente, was auch immer, das nicht ständig rumzickt sondern einfach funktioniert (Vorausgesetzt ich habe sie richtig verwendet. Bei falscher Verwendung bzw. Gefahr darf sie mich gerne darauf aufmerksam machen).

Kommentare: Guter Code kommt mit sehr wenig Kommentaren aus. Ausserdem machen die wenigsten Leute gute Kommentare. Besser ist es, wenn der Code selbsterklärend ist.

Portabilität: Da gibt es einen fliessenden Übergang zwischen portabel und nicht portabel. Von Delphi 2007 zu Delphi 2009 mag dein Code ohne Änderung laufen. Aber Pointers gibt es nicht überall.

Wenn ich bei einem Code-Review eine Assemblerlösung für dieses Problem sehe würde ich es zurückschicken.

Wie auch immer. Ich fand es nur ironisch, dass hier jeder versuchte, einen schnelleren Code als der vorherige zu schreiben. Dabei war keine Lösung überhaupt wirklich funktionsfähig. Deine übrigens auch nicht, wenn der String zum Beispiel 8-stellig ist.

Aber lassen wir's gut sein. Ich wollte nur darauf Aufmerksam machen, dass hier evtl. die falschen Prioritäten gesetzt werden. Es gibt viele verschiedene Programmier-Philosophien in der Literatur. Unix Philsophie, Extreme Programming Philsophie (YAGNI, OAOO, SPOT), etc.. Meistens heisst es, dass Code-Optimierung an letzter Stelle kommt. Und ich bin damit zu einem grossen Teil einverstanden.


Zuletzt bearbeitet von delfiphan am Fr 26.06.09 23:30, insgesamt 1-mal bearbeitet
MagicRain Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 154

WinXp, Win8, iOS
Delphi 7, Lazarus Pascal, Delphi 10.2 Starter, NetBeans Java
BeitragVerfasst: Fr 26.06.09 23:29 
Was ist denn jetzt hier passiert krieg ? :D aber danke euch allen!!!

MfG