Autor Beitrag
bs-Hobbit
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46

Windows Xp (Home/Prof.), Windows Server 2003, Linux
D7,D2005
BeitragVerfasst: Do 01.09.05 12:36 
Hallo,

habe folgendes Problem, ich habe ein Array

ausblenden Delphi-Quelltext
1:
TMeinArray = Array[1..255Of Char					


Das Steht jetzt z.B. drin:

Art Nr 123 ...

Also ein kleiner Text gefolgt von vielen Leerzeichen ;)

Ich will jetzt NUR den Text in einen String wandeln
also im srting soll dann stehen "Art Nr 123" ohne die Folge leerzeichen, aber mit den "Text Leerzeichen". Wie kriege ich jetzt raus, von wo an nur noch leerzeichen in dem array sind ?

Moderiert von user profile iconTino: Code- durch Delphi-Tags ersetzt.
Martin1966
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1068

Win 2000, Win XP
Delphi 7, Delphi 2005
BeitragVerfasst: Do 01.09.05 12:47 
Am besten gehst du Rückwärts vor.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
var
  a: TMeinArray 
  i: integer;
begin
  { ... }

  for i := high(a) downto low(a) do
    if a[i] <> #32 then
      begin
        // I hat jetzt die Position im Array wo sich zum letzten Mal 
        // kein Leerzeichen befindet - also das Ende von dem String. ;-)
 
        break;
      End;
end;


Lg Martin
ManuelGS
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 173

Win XP HE, Suse Linux
D6, D7, D2005 Personal
BeitragVerfasst: Do 01.09.05 12:47 
ich glaube der befehl, den du suchst, heißt rtrim (bzw. ltrim).

Gruß, Manuel.

_________________
"Leben ist gänzlich Bühne und Spiel; so lerne denn spielen
und entsage dem Ernst - oder erdulde das Leid." - Palladas von Alexandria
SMO
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 120
Erhaltene Danke: 18


D2005 Personal
BeitragVerfasst: Do 01.09.05 12:51 
Probier's mal so:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
var
  s: string;
  MeinArray: TMeinArray;

s := TrimRight(MeinArray);


Das schneidet alle Leerzeichen und Kontrollzeichen (alle Chars <= #32) von der rechten Seite des Texts ab. Analog dazu gibt es noch TrimLeft und Trim. Die Funktionen stammen aus der Unit SysUtils, die muss also im uses-Block stehen.
Martin1966
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1068

Win 2000, Win XP
Delphi 7, Delphi 2005
BeitragVerfasst: Do 01.09.05 12:56 
Kommen die Funktionen auch mit einem Array klar? Wusste ich noch gar nicht. ;-)
bs-Hobbit Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46

Windows Xp (Home/Prof.), Windows Server 2003, Linux
D7,D2005
BeitragVerfasst: Do 01.09.05 13:02 
Mein Delphi meint (Delphi 2005)

Den Befehl TrimRight gibts es nicht :*(

Muss ich eine Unit includen, die hilfe weiss damit auch nicht so recht was anzufangen ^^
Martin1966
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1068

Win 2000, Win XP
Delphi 7, Delphi 2005
BeitragVerfasst: Do 01.09.05 13:03 
Wer lesen kann ist klar im Vorteil. :-D

user profile iconSMO hat folgendes geschrieben:
Die Funktionen stammen aus der Unit SysUtils, die muss also im uses-Block stehen.
bs-Hobbit Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46

Windows Xp (Home/Prof.), Windows Server 2003, Linux
D7,D2005
BeitragVerfasst: Do 01.09.05 13:03 
Rückwertslauf methode ginge auch, aber TrimRight iterissiert mich jetzt einfach :wink: :roll:

Ich finde es eh zum Kotzen, das ich in einer Typisierten datei keine Strings speicher kann :evil:

Wenn ich mal was zum lesen hätte, delphi hilfe sacht mir dazu nix -.-

Danke für die schnelle hilfe

Thema abgeschlossen :D

Moderiert von user profile iconTino: Vier Beiträge zusammengefasst.
Martin1966
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1068

Win 2000, Win XP
Delphi 7, Delphi 2005
BeitragVerfasst: Do 01.09.05 13:10 
user profile iconbs-Hobbit hat folgendes geschrieben:
Wenn ich mal was zum lesen hätte, delphi hilfe sacht mir dazu nix -.-

Ich meine ja auch in diesem Topic. ;-)
bs-Hobbit Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46

Windows Xp (Home/Prof.), Windows Server 2003, Linux
D7,D2005
BeitragVerfasst: Do 01.09.05 13:15 
Oh, lol :oops:

aber meinst du ich lese den text soweit^^, ich seh den befehl, kopier ihn, und schau was delphi dazu sagt ;) und delphi war planlos
SMO
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 120
Erhaltene Danke: 18


D2005 Personal
BeitragVerfasst: Do 01.09.05 13:22 
user profile iconMartin1966 hat folgendes geschrieben:
Kommen die Funktionen auch mit einem Array klar? Wusste ich noch gar nicht. ;-)
Der Delphicompiler kann ein Array of Char automatisch in einen temporären String konvertieren, deshalb geht das hier ohne Probleme.

Schön, dass dein Problem gelöst ist, bs-Hobbit. Hier noch ein Tipp: jeder Beitrag von dir hat einen Knopf zum Bearbeiten. Wäre wohl besser, wenn du den benutzt, statt direkt hintereinander mehrere neue Beiträge zu schreiben, die auch noch kaum länger als ein Satz sind. Sowas wird in den meisten Foren nicht gern gesehen. ;)
Ah, und da hat auch schon ein fleißiger Admin die Beiträge zusammengefasst. :)
Martin1966
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1068

Win 2000, Win XP
Delphi 7, Delphi 2005
BeitragVerfasst: Do 01.09.05 13:45 
user profile iconbs-Hobbit hat folgendes geschrieben:
aber meinst du ich lese den text soweit^^, ich seh den befehl, kopier ihn, und schau was delphi dazu sagt ;) und delphi war planlos

Dann weißt du ja jetzt, dass es sinnvoll ist die Antworten komplett zu lesen und nicht nicht anschl. einen Frage zu stellen die bereits in einen Antwort an DICH beantwortet wurde. ;-)

Lg Martin
bs-Hobbit Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46

Windows Xp (Home/Prof.), Windows Server 2003, Linux
D7,D2005
BeitragVerfasst: Do 01.09.05 13:52 
Ja ok, sorry Leute ich werde mich ändern ;) ich bin ja auch erst seid einigen tagen Online ^^

Noch ne Frage zu den Array Of Char

Ich habe jetzt

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
TMeinRecord = Record
Name:TMeinArray;
Wert:Integer;
end;

TFile = File of TMeinRecord;


Gibt es überhaupt und evt noch eine andere lösung?

es ist ganz schön nervig, das ich keine strings in eine typisierte datei schreiben kann ...

Moderiert von user profile iconTino: Beiräge zusammengefasst.
Moderiert von user profile iconTino: Code- durch Delphi-Tags ersetzt.
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1335
Erhaltene Danke: 118

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Do 01.09.05 14:37 
das problem bei der verwendung des typs String mit typisierten dateien ist, das String intern kein echter statischer typ ist sondern eher ein objekt ist.
um dieses problem zu beheben könntest du ShortString verwenden. du solltest dir dann aber im klaren darüber sein das dein string dann nur 255 zeichen lang sein kann.

das ist dann das ergebnis:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
TMeinRecord = Record
  Name:ShortString;
  Wert:Integer;
end;
SMO
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 120
Erhaltene Danke: 18


D2005 Personal
BeitragVerfasst: Do 01.09.05 14:48 
user profile iconbs-Hobbit hat folgendes geschrieben:
Gibt es überhaupt und evt noch eine andere lösung?

es ist ganz schön nervig, das ich keine strings in eine typisierte datei schreiben kann ...


Nun, statt TMeinArray = Array[1..255Of Char; könntest du auch gleich den alten ShortString Typen benutzen, das ist vielleicht ein bisschen komfortabler, auch wenn es im Endeffekt keinen großen Unterschied macht.

Der Grund, warum der normale String Typ von Delphi nicht für typisierte Dateien verwendet werden kann, ist dass seine Größe variabel ist. Er kann über 2 Milliarden Zeichen aufnehmen, also bis zu 2 GB belegen. Für typisierte Dateien braucht man Datentypen, deren Größe statisch und undveränderlich ist. Bei einem ShortString ist das der Fall, er belegt immer 256 Bytes, selbst wenn nur ein einziger Buchstabe benutzt wird (das erste Byte gibt die Länge an, die restlichen 255 Bytes sind für den Text reserviert).

Mit ShortString sähe dein Record so aus:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
TMeinRecord = record
  Name: ShortString;  // oder auch Name: string[255]
  Wert: Integer;
end;

ShortString und string[255] sind äquivalent. Wenn "Name" nie länger als 30 Zeichen wird, dann könntest du natürlich auch string[30] benutzen, um Speicherplatz zu sparen. Ein "Name" würde dann 31 Bytes in der Datei belegen: 1 Byte für die tatsächliche Länge, 30 Bytes für den Inhalt.
Dadurch, dass bei diesen kurzen Strings, im Gegensatz zu einem Array of Char, die Länge explizit gespeichert ist, könntest du dir wahrscheinlich sogar das TrimRight sparen.
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Do 01.09.05 15:04 
Kleiner Tipp - nullindizierte Arrays sind zuweisungskompatibel mit PChar! ;)
Wenn du also statt array [1..255of Char das machst array [0..255of Char dann stellt sich das Problem gar nicht!

Generell zum Thema Strings, PChars etc. kann ich mein String-Tutorial empfehlen: www.manuel-poeter.de

Gruß, Motzi

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
bs-Hobbit Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46

Windows Xp (Home/Prof.), Windows Server 2003, Linux
D7,D2005
BeitragVerfasst: Fr 02.09.05 09:41 
Danke leute, ich habe jetzt ShortString verwendet, läuft alles soweit
thebe
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 128

WinXP Home
D6 Enterprise
BeitragVerfasst: Fr 02.09.05 10:22 
Sollte dein TMeinRecord auch noch mehr als den Namen und den Wert beinhalten, würde ich auf Klassen umsteigen, weil ich die bequemer zu handeln finde als Records. Ich würde eher sagen, anstatt typisierte Dateien zu benutzen, solltest eher Streams verwenden.

Guck Dir mal das folgende Code Beispiel an:

ausblenden volle Höhe 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:
30:
31:
32:
33:
type
   TMeinRecord = class
      Name: string;
      Wert: integer;

      procedure Serialize(s: TStream);
      procedure Deserialize(s: TStream);
   end;


// Serialize - Werte in einen Stream speichern
procedure TMeinRecord.Serialize(s: TStream);
var
   len: word;   // Benutzte nur ein word für die String Länge, weil ich denke das ein Name niemals über 65k Zeichen kommt
begin
   len := Length(Name);
   s.Write(len, 2);

   s.Write(Name[1], len);
   s.Write(Wert, 4);
end;

// Deserialize - Werte aus einem Stream auslesen
procedure TMeinRecord.Deserialize(s: TStream);
var
   len: word;   // s.o.
begin
   s.Read(len, 2);

   SetLength(Name, len);
   s.Read(Name[1], len);
   s.Read(Wert, 4);
end;


Ich denke mal, wenn Du mal alleine 100 Datensätze in deiner Datei drinne hast und sich diese Namen alle im Bereich zwischen 30 und 40 Zeichen bewegen, sparst dadurch schon min. 21,3 KB. (typisierte Datei: 25,5 KB. Datei basierend auf Streams und dieser Klasse: 3,2 - 4,2 KB)

[EDIT]
Der gesamte Code hier is aussem Kopf geschrieben, für Fehlerfreiheit kann ich nicht garantieren :)


Damit Du auch in den Genuß vom einfachem Zugreifen auf ein Array dieser "Record"-Klassen und dem einfachem Laden/Speichern in eine Datei kommst, hier noch nen bisserl was für Dich.

ausblenden volle Höhe 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:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
type
    TMeinRecordDatei = class
    private
        fArray: array of TMeinRecord;

        procedure SetLength(value: cardinal);
        function GetLength: cardinal;

        procedure SetArray(index: cardinal; value: TMeinRecord);
        function GetArray(index: cardinal): TMeinRecord;

    public
        property Items[index: cardinal]: TMeinRecord read GetArray write SetArray; default;
        Length: cardinal read GetLength write SetLength;

        procedure LoadFromFile(APath: TFileName);
        procedure SaveToFile(APath: TFileName);
    end;

procedure TMeinRecordDatei.SetLength(value: cardinal);
var
    oldlen: cardinal;
    newlen: cardinal;
    i: cardinal;
begin
    oldlen := Length(fArray);
    newlen := value;
    
    SetLength(fArray, value);

    if ( newlen > oldlen ) then
    begin
        for i := oldlen to newlen-1 do
            fArray[i] := TMeinRecord.Create;
    end
    else if ( oldlen > newlen ) then
    begin
        for i := newlen to oldlen-1 do
            fArray[i].Free;
    end;
end;

function TMeinRecordDatei.GetLength: cardinal;
begin
    result := Length(fArray);
end;

procedure TMeinRecordDatei.SetArray(index: cardinal; value: TMeinRecord);
begin
    if ( index >= Length(fArray) ) then
        exit;

    fArray[index] := value;
end;

function TMeinRecordDatei.GetArray(index: cardinal): TMeinRecord;
begin
    result := nil;

    if ( index >= Length(fArray) ) then
        exit;

    result := fArray[index];
end;

procedure TMeinRecordDatei.LoadFromFile(APath: TFileName);
var
    f: TFileStream;
    len: cardinal;
    i: cardinal;
begin
    f := nil;
    Length := 0// Array wird leer gemacht, hier kommt neuer Inhalt    

    try
        try
            if FileExists(APath) then
                f := TFileStream.Create(APath, fmOpenReadWrite or fmShareDenyNone)
            else
                exit;

            f.Read(len, 4);
            Length := len;

            for i := 0 to len-1 do
                fArray[i].Deserialize(f); 
        except
            Length := 0// Fehler beim Laden, das Array wird leer gemacht, wer weiß was alles drinne steht    
        end;
    finally
        if Assigned(f) then
            FreeAndNil(f);
    end;
end;

procedure TMeinRecordDatei.SaveToFile(APath: TFileName);
var
    f: TFileStream;
    len: cardinal;
    i: cardinal;
begin
    f := nil;

    try
        try
            if FileExists(APath) then
                f := TFileStream.Create(APath, fmOpenReadWrite or fmShareDenyNone)
            else
                f := TFileStream.Create(APath, fmCreate or fmShareDenyNone);

            len := Length;
            f.Write(len, 4);

            for i := 0 to len-1 do
                fArray[i].Serialize(f); 
        except
            // Something has to be done here
        end;
    finally
        if Assigned(f) then
            FreeAndNil(f);
    end;
end;


Soo...
und folgendermaßen könntest das Ding dann benutzen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
var
    datei: TMeinRecordDatei;
begin
    datei := TMeinRecordDatei.Create;
    datei.LoadFromFile('C:\somesave.dat');

    datei[3].Name := 'Helga Meier';
    datei[3].Wert := 42;

    datei.SaveToFile('C:\somesave.dat');
    datei.Free;
end;


Komfortabel, oder ?

MfG
- Thebe


Zuletzt bearbeitet von thebe am Fr 02.09.05 10:57, insgesamt 1-mal bearbeitet
Tino
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Veteran
Beiträge: 9839
Erhaltene Danke: 45

Windows 8.1
Delphi XE4
BeitragVerfasst: Fr 02.09.05 10:34 
Die Verwendung von Streams und so bitte in einem neuen Topic besprechen. Danke. ;-)

Gruß
Tino