Entwickler-Ecke
Algorithmen, Optimierung und Assembler - Array[1..2555] of Char --> Umwandeln in einen String
bs-Hobbit - Do 01.09.05 11:36
Titel: Array[1..2555] of Char --> Umwandeln in einen String
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 - Do 01.09.05 11: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 - Do 01.09.05 11:47
ich glaube der befehl, den du suchst, heißt rtrim (bzw. ltrim).
Gruß, Manuel.
SMO - Do 01.09.05 11: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 - Do 01.09.05 11:56
Kommen die Funktionen auch mit einem Array klar? Wusste ich noch gar nicht. ;-)
bs-Hobbit - Do 01.09.05 12: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 - Do 01.09.05 12:03
Wer lesen kann ist klar im Vorteil. :-D
SMO hat folgendes geschrieben: |
| Die Funktionen stammen aus der Unit SysUtils, die muss also im uses-Block stehen. |
bs-Hobbit - Do 01.09.05 12: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
Tino: Vier Beiträge zusammengefasst.
Martin1966 - Do 01.09.05 12: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 - Do 01.09.05 12: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 - Do 01.09.05 12: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 - Do 01.09.05 12: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 - Do 01.09.05 12: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 - Do 01.09.05 13: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 - Do 01.09.05 13: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 - Do 01.09.05 14: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:
http://www.manuel-poeter.de
Gruß, Motzi
bs-Hobbit - Fr 02.09.05 08:41
Danke leute, ich habe jetzt ShortString verwendet, läuft alles soweit
thebe - Fr 02.09.05 09: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:
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;
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.
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; 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
Tino - Fr 02.09.05 09:34
Die Verwendung von Streams und so bitte in einem neuen Topic besprechen. Danke. ;-)
Gruß
Tino
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!