Autor |
Beitrag |
bs-Hobbit
      
Beiträge: 46
Windows Xp (Home/Prof.), Windows Server 2003, Linux
D7,D2005
|
Verfasst: Do 01.09.05 12:36
Hallo,
habe folgendes Problem, ich habe ein Array
Delphi-Quelltext 1:
| TMeinArray = Array[1..255] Of 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 Tino: Code- durch Delphi-Tags ersetzt.
|
|
Martin1966
      
Beiträge: 1068
Win 2000, Win XP
Delphi 7, Delphi 2005
|
Verfasst: Do 01.09.05 12:47
Am besten gehst du Rückwärts vor.
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 break; End; end; |
Lg Martin
|
|
ManuelGS
      
Beiträge: 173
Win XP HE, Suse Linux
D6, D7, D2005 Personal
|
Verfasst: 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
      
Beiträge: 120
Erhaltene Danke: 18
D2005 Personal
|
Verfasst: Do 01.09.05 12:51
Probier's mal so:
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
      
Beiträge: 1068
Win 2000, Win XP
Delphi 7, Delphi 2005
|
Verfasst: Do 01.09.05 12:56
Kommen die Funktionen auch mit einem Array klar? Wusste ich noch gar nicht. 
|
|
bs-Hobbit 
      
Beiträge: 46
Windows Xp (Home/Prof.), Windows Server 2003, Linux
D7,D2005
|
Verfasst: 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
      
Beiträge: 1068
Win 2000, Win XP
Delphi 7, Delphi 2005
|
Verfasst: Do 01.09.05 13:03
Wer lesen kann ist klar im Vorteil.
SMO hat folgendes geschrieben: | Die Funktionen stammen aus der Unit SysUtils, die muss also im uses-Block stehen. |
|
|
bs-Hobbit 
      
Beiträge: 46
Windows Xp (Home/Prof.), Windows Server 2003, Linux
D7,D2005
|
Verfasst: Do 01.09.05 13:03
Rückwertslauf methode ginge auch, aber TrimRight iterissiert mich jetzt einfach
Ich finde es eh zum Kotzen, das ich in einer Typisierten datei keine Strings speicher kann
Wenn ich mal was zum lesen hätte, delphi hilfe sacht mir dazu nix -.-
Danke für die schnelle hilfe
Thema abgeschlossen
Moderiert von Tino: Vier Beiträge zusammengefasst.
|
|
Martin1966
      
Beiträge: 1068
Win 2000, Win XP
Delphi 7, Delphi 2005
|
Verfasst: Do 01.09.05 13:10
bs-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 
      
Beiträge: 46
Windows Xp (Home/Prof.), Windows Server 2003, Linux
D7,D2005
|
Verfasst: Do 01.09.05 13:15
Oh, lol
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
      
Beiträge: 120
Erhaltene Danke: 18
D2005 Personal
|
Verfasst: Do 01.09.05 13:22
Martin1966 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
      
Beiträge: 1068
Win 2000, Win XP
Delphi 7, Delphi 2005
|
Verfasst: Do 01.09.05 13:45
bs-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 
      
Beiträge: 46
Windows Xp (Home/Prof.), Windows Server 2003, Linux
D7,D2005
|
Verfasst: 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
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 Tino: Beiräge zusammengefasst.
Moderiert von Tino: Code- durch Delphi-Tags ersetzt.
|
|
Sinspin
      
Beiträge: 1335
Erhaltene Danke: 118
Win 10
RIO, CE, Lazarus
|
Verfasst: 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:
Delphi-Quelltext 1: 2: 3: 4:
| TMeinRecord = Record Name:ShortString; Wert:Integer; end; |
|
|
SMO
      
Beiträge: 120
Erhaltene Danke: 18
D2005 Personal
|
Verfasst: Do 01.09.05 14:48
bs-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..255] Of 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:
Delphi-Quelltext 1: 2: 3: 4:
| TMeinRecord = record Name: ShortString; 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
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Do 01.09.05 15:04
Kleiner Tipp - nullindizierte Arrays sind zuweisungskompatibel mit PChar!
Wenn du also statt array [1..255] of Char das machst array [0..255] of 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 
      
Beiträge: 46
Windows Xp (Home/Prof.), Windows Server 2003, Linux
D7,D2005
|
Verfasst: Fr 02.09.05 09:41
Danke leute, ich habe jetzt ShortString verwendet, läuft alles soweit
|
|
thebe
      
Beiträge: 128
WinXP Home
D6 Enterprise
|
Verfasst: 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:
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;
procedure TMeinRecord.Serialize(s: TStream); var len: word; begin len := Length(Name); s.Write(len, 2);
s.Write(Name[1], len); s.Write(Wert, 4); end;
procedure TMeinRecord.Deserialize(s: TStream); var len: word; 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.
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; 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; 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 end; finally if Assigned(f) then FreeAndNil(f); end; end; |
Soo...
und folgendermaßen könntest das Ding dann benutzen:
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
      

Beiträge: 9839
Erhaltene Danke: 45
Windows 8.1
Delphi XE4
|
Verfasst: Fr 02.09.05 10:34
Die Verwendung von Streams und so bitte in einem neuen Topic besprechen. Danke.
Gruß
Tino
|
|