Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi mehrere Strings in einen String vereinen (mit fixer Länge + festen Positionen) (https://www.delphipraxis.net/171663-mehrere-strings-einen-string-vereinen-mit-fixer-laenge-festen-positionen.html)

Helmi 17. Nov 2012 22:06

mehrere Strings in einen String vereinen (mit fixer Länge + festen Positionen)
 
Hallo,

ich steh gerade auf dem Schlauch.

Ich habe folgende Bedingungen an einen AnsiString:
  1. genau 40 Zeichen lang.
  2. Ab 1. bis 3. Stelle soll der Inhalt eines anderen Strings (S_Linie) eingefügt werden.
  3. 4. Stelle = Leerzeichen
  4. 5. bis 33. Stelle = Inhalt eines zweiten Strings (S_Ziel)
  5. 35. Stelle = Leerzeichen
  6. 36. bis 40. Stelle = Inhalt eines dritten Strings (S_Laenge)

Ich habe es mit Insert probiert, als auch mit Format.
Aber bei
Delphi-Quellcode:
Insert
wird der Text trotzdem länger (irgendwie auch klar) und bei
Delphi-Quellcode:
Format
(z. B. mit %.3s als Argument) bekomm ich einen Argumentfehler.

Wie kann ich den String zusammenbauen mit den Randbedingungen?
Ausser jeden String in einer Schleife durchzugehen und Zeichen für Zeichen im End-String zu positionieren

Popov 17. Nov 2012 22:19

AW: mehrere Strings in einen String vereinen (mit fixer Länge + festen Positionen)
 
Gibt es einige Möglichkeiten. Die erste:

Delphi-Quellcode:
var
  a, b, c, x: String;
begin
  x := '1234567890123456789012345678901234567890'; //40Zeichen
  a := 'abc'; //3 Zeichen
  b := 'ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖ'; //28
  c := 'äöüß#';

  Delete(x, 1, 3);
  Insert(a, x, 1);

  x[4] := ' ';

  Delete(x, 5, 28);
  Insert(b, x, 5);

  x[35] := ' ';

  Delete(x, 36, 5);
  Insert(c, x, 36);

  ShowMessage(x);
  ShowMessage(IntToStr(Length(x)));
end;
Eine andere:
Delphi-Quellcode:
var
  i: Integer;
  a, b, c, x: String;
begin
  x := '1234567890123456789012345678901234567890'; //40Zeichen
  a := 'abc'; //3 Zeichen
  b := 'ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖ'; //28
  c := 'äöüß#';

  //hier aber vorsicht! zuerst prüfen ob x lang genug ist und nicht überschritten wird

  for i := 1 to Length(a) do
    x[1 - 1 + i] := a[i];

  x[4] := ' ';

  for i := 1 to Length(b) do
    x[5 - 1 + i] := b[i];


  x[35] := ' ';

  for i := 1 to Length(c) do
    x[36 - 1 + i] := c[i];

  ShowMessage(x);
  ShowMessage(IntToStr(Length(x)));
end;

Helmi 17. Nov 2012 22:23

AW: mehrere Strings in einen String vereinen (mit fixer Länge + festen Positionen)
 
ich vergaß zu erwähnen, dass die einzufügenden Strings nicht unbedingt genau die Länge haben, die für sie definiert sind.
Also der erste String z. B. kann 3 Zeichen, muss aber nicht.

Momentan mach ich es so:
Delphi-Quellcode:
  //auf 40 Zeichen setzen (=max. Länge der Zeile des LCD-Moduls)
  SetLength(S_Text, 40);

  S_Text := StringOfChar(#32, length(S_Text));

  for i := 1 to length(S_Linie) do
    begin
      If i > 3 then
        break;

      S_Text[i] := S_Linie[i];
    end;

  for i := 1 to length(S_Ziel) do
    begin
      If i > 39 then
        break;

      S_Text[i + 4] := S_Ziel[i];
    end;

Popov 17. Nov 2012 22:26

AW: mehrere Strings in einen String vereinen (mit fixer Länge + festen Positionen)
 
Also solange es drunter bleibt ist das zweite Beispiel richtig. Wenn es länger werden kann, dann zuerst prüfen.

Helmi 17. Nov 2012 22:28

AW: mehrere Strings in einen String vereinen (mit fixer Länge + festen Positionen)
 
Zitat:

Zitat von Popov (Beitrag 1191759)
Also solange es drunter bleibt ist das zweite Beispiel richtig. Wenn es länger werden kann, dann zuerst prüfen.

So mach ich es jetzt (siehe meinem 2. Post) - nur vielleicht da ja was einfacheres

Uwe Raabe 17. Nov 2012 22:30

AW: mehrere Strings in einen String vereinen (mit fixer Länge + festen Positionen)
 
Geht auch einfacher:

Delphi-Quellcode:
uses
  System.SysUtils, System.StrUtils;
...
  result := Format('%-3s %-28s %-5s', [LeftStr(a, 3), LeftStr(b, 28), LeftStr(c, 5)]);

Helmi 17. Nov 2012 22:39

AW: mehrere Strings in einen String vereinen (mit fixer Länge + festen Positionen)
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1191761)
Geht auch einfacher:

Delphi-Quellcode:
uses
  System.SysUtils, System.StrUtils;
...
  result := Format('%-3s %-28s %-5s', [LeftStr(a, 3), LeftStr(b, 28), LeftStr(c, 5)]);

So einfach wollt ich es :-)
Wieso hab ich das "-Zahl" nicht in der Doku gefunden? :gruebel:

Sir Rufo 17. Nov 2012 23:46

AW: mehrere Strings in einen String vereinen (mit fixer Länge + festen Positionen)
 
Weil du es überlesen hast?
Zitat:

Formatbezeichner werden in der folgenden Form angegeben:
"%" [Index ":"] ["-"] [Breite] ["." Genauigkeit] Typ
Jeder Formatbezeichner beginnt mit dem Zeichen %. Auf das Prozentzeichen folgen die folgenden Elemente (in der aufgeführten Reihenfolge):
Ein optionaler Argumentindex-Bezeichner mit dem Offset Null (erstes Element hat den Index 0): [Index ":"].
Eine optionale Angabe für die linksbündige Ausrichtung: ["-"].
Eine optionale Breitenangabe: [Breite].
Eine optionale Genauigkeitsangabe: ["." Genauigkeit].
Das Zeichen für den Konvertierungstyp: Typ.
http://docwiki.embarcadero.com/Libra...ysUtils.Format

Helmi 17. Nov 2012 23:49

AW: mehrere Strings in einen String vereinen (mit fixer Länge + festen Positionen)
 
Zitat:

Zitat von Sir Rufo (Beitrag 1191770)
Weil du es überlesen hast?

Im Büro hätt ich jetzt gesagt:
Zitat:

Weil ich einfach alt werd!
:-D

Und ja - ich gestehe - ich habs echt überlesen!

himitsu 18. Nov 2012 02:17

AW: mehrere Strings in einen String vereinen (mit fixer Länge + festen Positionen)
 
Delphi-Quellcode:
result := Format('%-3.3s %-28.28s %-5.5s', [S_Linie, S_Ziel, S_Laenge]);


Für Strings (%s) :
- = Linkbündig
*. = Minimallänge (aufgefüllt mit Leerzeichen)
.* = Maximallänge (mehr wird abgeschnitten)

Aber was soll eigentlich ein Argumentfehler sein?



Zitat:

Delphi-Quellcode:
  SetLength(S_Text, 40);
  S_Text := StringOfChar(#32, length(S_Text));

Das ist ein klein bissl sinnlos/doppeltgemoppelt. :zwinker:
Delphi-Quellcode:
  S_Text := StringOfChar(#32, 40);




Aber nur noch was zum Prinzipiellen:

Falls S_Linie und Co. auch länger sein können, als du es haben sillst, dann jeweils
Delphi-Quellcode:
S_Linie
gegen
Delphi-Quellcode:
Copy(S_Linie, 1, 3)
, bzw.
Delphi-Quellcode:
LeftStr(S_Linie, 3)
austauschen.

Delphi-Quellcode:
S := S_Linie + StringOfChar(' ', 4 - Length(S_Linie))
   + S_Ziel + StringOfChar(' ', 28{30?} - Length(S_Ziel))
   + S_Laenge + StringOfChar(' ', 5 - Length(S_Laenge));
PS: In deinem Post #1 kann ich nicht erkennen, was in Stelle 34 rein soll. :gruebel:

3 + 1 + 28 + 1 + 5 = 38
In #1 hatte ich 29 ausgerechnet, aber auch das reicht noch nicht.



Ach ja, du kannst deine Variable "Länge" jetzt auch
Delphi-Quellcode:
S_Länge
nennen. :angle:

Und wieso sind Linie und Länge eigentlich keine Integer? :angle2:

Sir Rufo 18. Nov 2012 02:52

AW: mehrere Strings in einen String vereinen (mit fixer Länge + festen Positionen)
 
@himitsu 5. bis 33. Stelle sind 29 Zeichen und nicht 28 ;)
36. bis 40. Stelle sind ja auch 5 Zeichen ;)

Somit sind es 39 Zeichen die er beschrieben hat, aber er hat sich mit der 34. Stelle vertan und unter den Tisch fallen lassen ;)
und dann sind es 40

himitsu 18. Nov 2012 03:03

AW: mehrere Strings in einen String vereinen (mit fixer Länge + festen Positionen)
 
Sag ich ja :mrgreen:

Zitat:

3 + 1 + 28 + 1 + 5 = 38
In #1 hatte ich 29 ausgerechnet, aber auch das reicht noch nicht.
Aber hier in den Codes verwenden alle 28 :zwinker: (vermutlich ein Copy&Paste-Error, ausgehend von #2)
Die 29 hatte ich mir auch ausgerrechnet.
Aber dennoch fehlt ein Zeichen (die 34), da er ja 40 Zeichen haben will.

3 + 1 + 29 + 1 + 5 = 39

Helmi 18. Nov 2012 10:18

AW: mehrere Strings in einen String vereinen (mit fixer Länge + festen Positionen)
 
Zitat:

Zitat von himitsu (Beitrag 1191781)
Delphi-Quellcode:
result := Format('%-3.3s %-28.28s %-5.5s', [S_Linie, S_Ziel, S_Laenge]);


Für Strings (%s) :
- = Linkbündig
*. = Minimallänge (aufgefüllt mit Leerzeichen)
.* = Maximallänge (mehr wird abgeschnitten)

Danke für die Erklärung - irgendwie ist die Hilfe da nicht so präzise

Zitat:

Zitat von himitsu (Beitrag 1191781)
Aber was soll eigentlich ein Argumentfehler sein?

Ok - das war etwas laienhaft ausgedrückt.



Zitat:

Zitat von himitsu (Beitrag 1191781)
Zitat:

Delphi-Quellcode:
  SetLength(S_Text, 40);
  S_Text := StringOfChar(#32, length(S_Text));

Das ist ein klein bissl sinnlos/doppeltgemoppelt. :zwinker:
Delphi-Quellcode:
  S_Text := StringOfChar(#32, 40);

Ja und Nein! - Ich gib gern Längen nur einmal an. Wenn ich die Länge dann verändere, verändert sich automatisch alles mit.
(Ok - da es hier genau 40 sind, hätte man auch 40 reinschreiben können)

Zitat:

Zitat von himitsu (Beitrag 1191781)
3 + 1 + 28 + 1 + 5 = 38
In #1 hatte ich 29 ausgerechnet, aber auch das reicht noch nicht.

Ich muss gestehen - ich hab mich selbst verhaut - ich bin auch auf weniger Stellen gekommen, als ich wollte.
Habs dann erst bemerkt, als ich den String an ein LCD-Modul gesendet hatte (daher auch die 40 = max. Zeichen pro Zeile)
(Man sollte so spät nicht mehr rechnen)

Zitat:

Zitat von himitsu (Beitrag 1191781)
Ach ja, du kannst deine Variable "Länge" jetzt auch
Delphi-Quellcode:
S_Länge
nennen. :angle:

Das ist mir bekannt - aber ich kann mich damit nicht anfreunden - ich bleib lieber bei ae, ue oder oe

Zitat:

Zitat von himitsu (Beitrag 1191781)
Und wieso sind Linie und Länge eigentlich keine Integer? :angle2:

"Linie" und "Länge" werden aus einer StringGrid-Zeile gelesen. Daher der String.
Da ich es weiter dann auch als String benötige, wandle ich es nicht unnötigerweise erst in einen Integer.

Auserdem ist Linie keine Zahl - sondern eine Linien-Angabe einer U-Bahn :-)

Sir Rufo 18. Nov 2012 10:48

AW: mehrere Strings in einen String vereinen (mit fixer Länge + festen Positionen)
 
Passt jetzt zwar nicht zu der Ausgangs Problematik, aber mir sträuben sich gerade alle Nackenhaare bei:
Zitat:

Zitat von Helmi (Beitrag 1191800)
"Linie" und "Länge" werden aus einer StringGrid-Zeile gelesen. Daher der String.
Da ich es weiter dann auch als String benötige, wandle ich es nicht unnötigerweise erst in einen Integer.

Auserdem ist Linie keine Zahl - sondern eine Linien-Angabe einer U-Bahn :-)

Das macht man doch nicht. Hierfür würde sich perfekt das Visitor-Pattern von Uwe Raabe anbieten.

Basierend auf der unit aus diesem Artikel sieht das dann so aus:
Delphi-Quellcode:
uses
  ..., uVisitor;

type
  TSubway = class
    property Line : string;
    property Destination : string;
  end;

  TSubwayArrival = class
    property Subway : TSubway;
    property ArrivalAt : TDateTime;
  end;

  // Der Einfachheit halber wird hier nur in eine Variable geschrieben
  // Es könnte aber auch direkt die Ausgabe an das LCD-Modul erfolgen
  // Oder an eine Klasse, die das LCD-Modul selber betreut :o)
  TLCDVisitor = class( TVisitor )
  private
    FLine : string;
  public
    property Line : string read FLine;
  published
    procedure VisitSubwayArrival( Instance : TSubwayArrival );
  end;

procedure TLCDVisitor.VisitSubwayArrival( Instance : TSubwayArrival );
begin
  FLine := { hier jetzt der Code um die Instanz auszugeben }
end;
und diesen Visitor hat man im 0, auch um weitere Klassen erweitert, um auch diese auf dem LCD darstellen zu können.

Ja und der Aufruf sieht dann immer so aus (egal welche Instanz und welche Klasse auch immer):
Delphi-Quellcode:
MyLCDVisitor.Visit( SomeInstance );

Helmi 18. Nov 2012 10:54

AW: mehrere Strings in einen String vereinen (mit fixer Länge + festen Positionen)
 
Zitat:

Zitat von Sir Rufo (Beitrag 1191804)
Passt jetzt zwar nicht zu der Ausgangs Problematik, aber mir sträuben sich gerade alle Nackenhaare bei:

Was ist jetzt daran so schlimm?
Ich lese den Inhalt eine Zelle aus, der als String vorliegt und in eine String-Variable geschrieben wird - was ist daran jetzt auf einmal so verwerflich?
Seit wann darf man das nicht mehr?

Sir Rufo 18. Nov 2012 11:39

AW: mehrere Strings in einen String vereinen (mit fixer Länge + festen Positionen)
 
Zitat:

Zitat von Helmi (Beitrag 1191805)
Zitat:

Zitat von Sir Rufo (Beitrag 1191804)
Passt jetzt zwar nicht zu der Ausgangs Problematik, aber mir sträuben sich gerade alle Nackenhaare bei:

Was ist jetzt daran so schlimm?
Ich lese den Inhalt eine Zelle aus, der als String vorliegt und in eine String-Variable geschrieben wird - was ist daran jetzt auf einmal so verwerflich?
Seit wann darf man das nicht mehr?

Seit dem man nicht mehr mit dem Foto des Geldscheins bezahlen darf :mrgreen:

Uwe Raabe 18. Nov 2012 12:27

AW: mehrere Strings in einen String vereinen (mit fixer Länge + festen Positionen)
 
Zitat:

Zitat von himitsu (Beitrag 1191781)
Für Strings (%s) :
- = Linkbündig
*. = Minimallänge (aufgefüllt mit Leerzeichen)
.* = Maximallänge (mehr wird abgeschnitten)

[/QUOTE]

Stimmt! Damit kann man das auch noch einfacher schreiben und StrUtils weglassen:

Delphi-Quellcode:
result := Format('%-3.3s %-29.29s %-5.5s', [a, b, c]);


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:50 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-2025 by Thomas Breitkreuz