Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Auf den letzten char in einer Datei zugreifen (https://www.delphipraxis.net/203448-auf-den-letzten-char-einer-datei-zugreifen.html)

kagi3624 18. Feb 2020 09:41

Auf den letzten char in einer Datei zugreifen
 
Hallo, unfreiwilliger Delphi 6 User hier,

wie kann ich auf den letzten Char in der Textdatei zugreifen um den eventuell zu löschen? Hintergrund: Ich schreibe in eine CSV Einträge und möchte das letzte Komma einfach löschen, ohne dass es in den EOF zugreift oder mir sonstwie um die Ohren fliegt.

Danke! :)

Luckie 18. Feb 2020 09:47

AW: Auf den letzten char in einer Datei zugreifen
 
Lad die Datei in eine Stringliste. In der Eigenschaft Text hast du dann den Inhalt der Datei. Zum Löschen eines Zeichens, guck dir mal in der Hilfe Delete an: http://www.bergt.de/workshop/delphi/html/funktion21.htm

Klaus01 18. Feb 2020 09:52

AW: Auf den letzten char in einer Datei zugreifen
 
.. ich würde die Datei in einen Stream laden, das Ende des Streams springen und schauen was für ein Zeichen sich da befindet.

Grüße
Klaus

Moombas 18. Feb 2020 09:56

AW: Auf den letzten char in einer Datei zugreifen
 
Vom Prinzip:

Delphi-Quellcode:
sl := TStringlist.Create;
sl.LoadFromFile(Text.csv);

sl.Strings[Liste.Count-1]:= copy(sl.Strings[Liste.Count-1], 1, Length(sl.Strings[Liste.Count-1])-1); //Letztes Zeichen löschen
Ungetestet, bin mir gerade wegen der Zuweisung nicht sicher.

Luckie 18. Feb 2020 09:57

AW: Auf den letzten char in einer Datei zugreifen
 
Eine Stringliste behandelt die Textdatei als das, was sie ist, als Zeichenkette. Und darauf kann man ganz einfach die Funktionen zur Zeichenkettenmanipulation anwenden.

@Moombas: Und warum nicht Delete?

Delphi-Quellcode:
Delete ( var Source : string; StartChar : Integer; Count : Integer )

p80286 18. Feb 2020 09:58

AW: Auf den letzten char in einer Datei zugreifen
 
Das letzte Zeichen einer Datei erreichst Du mit
Delphi-Quellcode:
seek(filesize-2)
aber
Zitat:

Zitat von kagi3624 (Beitrag 1457746)
Ich schreibe in eine CSV Einträge und möchte das letzte Komma einfach löschen, ohne dass es in den EOF zugreift oder mir sonstwie um die Ohren fliegt.

warum das? Meiner Meinung nach geht nichts über eine vernünftige Feldbegrenzung und warum solltest du überhaupt hinter dem Dateiende zugreifen?

Luckie hat ja schon den Weg der üblichen Datenbehandlung beschrieben.

Gruß
K-H

Moombas 18. Feb 2020 10:05

AW: Auf den letzten char in einer Datei zugreifen
 
Zitat:

Zitat von Luckie (Beitrag 1457753)
@Moombas: Und warum nicht Delete?

War mir jetzt zu einfach ^^ ... klar kann man auch

Delphi-Quellcode:
Delete(sl.Strings[sl.Count-1], length(sl.Strings[sl.Count-1]) - 1, 1);

nehmen^^

kagi3624 18. Feb 2020 10:07

AW: Auf den letzten char in einer Datei zugreifen
 
Zitat:

Zitat von p80286 (Beitrag 1457754)
warum das? Meiner Meinung nach geht nichts über eine vernünftige Feldbegrenzung und warum solltest du überhaupt hinter dem Dateiende zugreifen?
Gruß
K-H

Delphi (6?) behandelt ja auch nicht initialisierte Objekte als schon vorhandene Objekte und reicht die dann auch feucht fröhlich an andere Funktionen usw weiter. Man darf dann Stundenlang suchen, wo man dann T.create(); und nicht T := Tclass.Create(); hingedonnert hat oder gar weggelassen...Also mein Frustlevel mit Delphi ist ausgereizt.

p80286 18. Feb 2020 10:35

AW: Auf den letzten char in einer Datei zugreifen
 
Zitat:

Zitat von kagi3624 (Beitrag 1457757)

Delphi (6?) behandelt ja auch nicht initialisierte Objekte als schon vorhandene Objekte und reicht die dann auch feucht fröhlich an andere Funktionen usw weiter. Man darf dann Stundenlang suchen, wo man dann T.create(); und nicht T := Tclass.Create(); hingedonnert hat oder gar weggelassen...Also mein Frustlevel mit Delphi ist ausgereizt.

Mmm das passiert auch mir manchmal, ich halte das aber für meine Dusseligkeit.

Gruß
K-H

KodeZwerg 18. Feb 2020 10:36

AW: Auf den letzten char in einer Datei zugreifen
 
Zitat:

Zitat von kagi3624 (Beitrag 1457746)
wie kann ich auf den letzten Char in der Textdatei zugreifen

very oldschool, nur zum auslesen des letzten zeichen erstmal gedacht...
Delphi-Quellcode:
var
  DateiHandle: THandle;
  dwBytesRead: Cardinal;
  Buf: Byte;
begin
  DateiHandle := CreateFile('Dateiname.csv', GENERIC_READ, 0, nil, OPEN_EXISTING, 0, 0);
  if DateiHandle <> INVALID_HANDLE_VALUE then
  begin
    SetFilePointer(DateiHandle, -1, nil, FILE_END);
    ReadFile(DateiHandle, Buf, 1, dwBytesRead, nil);
    // Buf checken machen tuen
    ShowMessage(IntToStr(Buf));
    CloseHandle(DateiHandle);
  end;
end;

Dennis07 18. Feb 2020 10:58

AW: Auf den letzten char in einer Datei zugreifen
 
Zitat:

Zitat von kagi3624 (Beitrag 1457746)
Hallo, unfreiwilliger Delphi 6 User hier

Wieso das? Es gibt doch mittlerweile die Community Edition...

Zitat:

Zitat von kagi3624 (Beitrag 1457746)
wie kann ich auf den letzten Char in der Textdatei zugreifen um den eventuell zu löschen? Hintergrund: Ich schreibe in eine CSV Einträge und möchte das letzte Komma einfach löschen, ohne dass es in den EOF zugreift oder mir sonstwie um die Ohren fliegt.

Entweder über eine TStringList, oder über einen TFileStream, oder über die (veralteten) TextFile-Routinen.

himitsu 18. Feb 2020 11:08

AW: Auf den letzten char in einer Datei zugreifen
 
Bei der StringListe aufpassen, dass es nicht knallt, sollte die Datei leer sein und einfach so ohne Prüfung auf Count-1 zugegriffen werden,
bzw. das letzte Char, wenn es nichts in der Zeile gibt.

PS: TStringList hängt beim Speichern einen Zeilenumbruch hinter jede Zeile, selbst wenn es beim Einlesen hinter der letzten Zeile keinen Zeilenumbruch gab.


CreateFile, SetFilePointer, ReadFile, MSDN-Library durchsuchenSetEndOfFile, CloseHandle
oder
Delphi-Quellcode:
S := TFileStream.Create(...);
//S.Position := S.Size - 1;
//if AnsiChar(S.Read(..., 1)) = ',' then
S.Size := S.Size - 1;
S.Free;
CreateFile/TFileStream knallt nichts, außer du willst es.
Ein Read/SetPosition hinter das Ende wird auf das Ende zurückgesetzt, bzw. stoppt dort.
Einige Read-Methoden (die ohne Result), werfen eine Exception, wenn sie nicht genug lesen/schreiben konnten und die mit Result sagen dir wieviel sie wirklich gemacht hatten (wenn du nicht vergisst die Results auszuwerten).
Read/Write vs. ReadBuffer/WriteBuffer

kagi3624 18. Feb 2020 12:35

AW: Auf den letzten char in einer Datei zugreifen
 
Zitat:

Zitat von Moombas (Beitrag 1457755)
Zitat:

Zitat von Luckie (Beitrag 1457753)
@Moombas: Und warum nicht Delete?

War mir jetzt zu einfach ^^ ... klar kann man auch

Delphi-Quellcode:
Delete(sl.Strings[Liste.Count-1], length(sl.Strings[Liste.Count-1]) - 1, 1);

nehmen^^

Was ist denn 'Liste.count'..wo kommt das her?

Bbommel 18. Feb 2020 12:49

AW: Auf den letzten char in einer Datei zugreifen
 
Zitat:

Was ist denn 'Liste.count'..wo kommt das her?
Das soll wohl
Delphi-Quellcode:
sl.Count
heißen. Also die Anzahl der Elemente (=Anzahl der Zeilen) in der Stringliste sl. Die Anweisung soll in der letzten Zeile das letzte Zeichen löschen.


Zitat:

Delphi (6?) behandelt ja auch nicht initialisierte Objekte als schon vorhandene Objekte und reicht die dann auch feucht fröhlich an andere Funktionen usw weiter.
Ist zwar etwas von der eigentlichen Frage weg, aber dennoch kurz der Hiwneis, damit aus deinem Frust nicht komplette Abneigung wird: eigentlich gibt es bei Delphi Compiler-Warnungen, wenn du auf Variablen (Objekte oder sonst etwas) lesend zugreifst, bevor sie initailisiert wurden. Wenn das nicht der Fall ist, dann ist ggf. im Code noch etwas anderes nicht in Ordnung oder die Warnungen sind ausgeschaltet. Kannst ja bei Interesse mal einen neuen Thread zu dem Thema aufmachen, wenn du Hilfe brauchst herauszufinden, warum es keine Warnung gab.

Moombas 18. Feb 2020 12:58

AW: Auf den letzten char in einer Datei zugreifen
 
Sorry, Bbommel hat recht, das war ein Copy/Paste Fehler.

So wäre es richtig bzw. Luckie hat ja auch schon die Anwendung von Delete gepostet.
Delphi-Quellcode:
Delete(sl.Strings[sl.Count-1], length(sl.Strings[sl.Count-1]) - 1, 1);

kagi3624 18. Feb 2020 13:05

AW: Auf den letzten char in einer Datei zugreifen
 
Zitat:

Zitat von Moombas (Beitrag 1457786)
Sorry, Bbommel hat recht, das war ein Copy/Paste Fehler.

So wäre es richtig bzw. Luckie hat ja auch schon die Anwendung von Delete gepostet.
Delphi-Quellcode:
Delete(sl.Strings[sl.Count-1], length(sl.Strings[sl.Count-1]) - 1, 1);

Ich bekomme aber folgenden Fehler bei dieser Zeile...

Delphi-Quellcode:
[Fehler] FRMMAIN.pas(3782): Konstantenobjekt kann nicht als Var-Parameter weitergegeben werden

Luckie 18. Feb 2020 13:24

AW: Auf den letzten char in einer Datei zugreifen
 
Delphi-Quellcode:
var
  sl: TStringList;
  s: String;
Beginn
  // ...;
  s := sl.Text;
  Delete(s, 0, length(s)-1);
  sl.Text := s;
  sl.SaveToFile;

DasWolf 18. Feb 2020 13:27

AW: Auf den letzten char in einer Datei zugreifen
 
Zitat:

Zitat von kagi3624 (Beitrag 1457788)
Zitat:

Zitat von Moombas (Beitrag 1457786)
Sorry, Bbommel hat recht, das war ein Copy/Paste Fehler.

So wäre es richtig bzw. Luckie hat ja auch schon die Anwendung von Delete gepostet.
Delphi-Quellcode:
Delete(sl.Strings[sl.Count-1], length(sl.Strings[sl.Count-1]) - 1, 1);

Ich bekomme aber folgenden Fehler bei dieser Zeile...

Delphi-Quellcode:
[Fehler] FRMMAIN.pas(3782): Konstantenobjekt kann nicht als Var-Parameter weitergegeben werden

Einfach den Zwischenschritt über eine Variable gehen.

Delphi-Quellcode:
var
  s: string;
begin
  s := sl.Strings[sl.Count-1];
  s := Trim(s);
  Delete(s, length(s), 1);
  sl.Strings[sl.Count-1] := s;
end;

Luckie 18. Feb 2020 13:39

AW: Auf den letzten char in einer Datei zugreifen
 
Das trim ist eine gute Idee.

kagi3624 18. Feb 2020 13:54

AW: Auf den letzten char in einer Datei zugreifen
 
Habe das jetzt über TFileStream gelöst. Ich kann meinen Kopf nicht über die Tatsache wickeln warum bei dem String der Index mit 1 und nicht 0, so wie sonst, anfängt.

Code:
procedure exportToCSV(Eintrag : string);
var
  strm : TFileStream;
  n : longint;
begin
  strm := TFileStream.Create('file.csv',fmCreate);
  n := Length(Eintrag);
  try
    strm.Position := 0;
    strm.Write(Eintrag[1], n);
    strm.Size := strm.Size - 1;
  finally
    strm.Free();
  end;
end;

Luckie 18. Feb 2020 14:06

AW: Auf den letzten char in einer Datei zugreifen
 
Warum einfach, wenn es kompliziert geht. Berücksichtigst du auch, ob es ANSI oder Unicode ist, wenn du ein Byte abschheidest?

freimatz 18. Feb 2020 14:11

AW: Auf den letzten char in einer Datei zugreifen
 
Zitat:

Zitat von kagi3624 (Beitrag 1457795)
Habe das jetzt über TFileStream gelöst. Ich kann meinen Kopf nicht über die Tatsache wickeln warum bei dem String der Index mit 1 und nicht 0, so wie sonst, anfängt.

Wie kommst Du drauf, dass es sonst bei 0 anfängt? Was ist bei dir "sonst"?

kagi3624 18. Feb 2020 14:14

AW: Auf den letzten char in einer Datei zugreifen
 
Zitat:

Zitat von freimatz (Beitrag 1457798)
Wie kommst Du drauf, dass es sonst bei 0 anfängt? Was ist bei dir "sonst"?

Arrays?

Moombas 18. Feb 2020 14:14

AW: Auf den letzten char in einer Datei zugreifen
 
Zumal du den String immer übergibst beim Aufruf deiner Funktion anstatt "wirklich" die Datei und deren letzte Zeile auszulesen... irgendwie macht deine Lösung in meinen Augen nicht das was du eigentlich gefragt hast...

- Du rufst die Funktion mit dem String "abcxyz" auf.
- Du weist eine csv einem Stream zu
- Definierst die Länge deines übergebenen Strings
- Schreibst deinen String 1:1 in die csv
- Schneidest vom Stream 1 Byte ab (siehe Hinweis von Luckie!)

...

Du willst also bei JEDEM Eintrag in die CSV das letzte Zeichen abschneiden!?
Warum machst du das nicht BEVOR du ihn in die CSV schreibst!?

....

Und wegen 1 und 0 habe ich mir das generell mal so gemerkt: Geht es um die Position starte mit 0, geht es um das Zeichen starte mit 1.
Ob das nun immer hin haut weiß ich nicht aber bisher passte es.

Sherlock 18. Feb 2020 15:36

AW: Auf den letzten char in einer Datei zugreifen
 
Darf ich kurz zur Klarstellung etwas dazwischen fragen? Die CSV Datei erstellst Du doch selbst, richtig? Warum nicht zum Zeitpunkt der Erstellung das überflüssige Zechen entfernen/vermeiden?

Sherlock

kagi3624 19. Feb 2020 06:58

AW: Auf den letzten char in einer Datei zugreifen
 
Zitat:

Zitat von Sherlock (Beitrag 1457818)
Darf ich kurz zur Klarstellung etwas dazwischen fragen? Die CSV Datei erstellst Du doch selbst, richtig? Warum nicht zum Zeitpunkt der Erstellung das überflüssige Zechen entfernen/vermeiden?

Sherlock

Hallo Sherlock...weil ich in Delphi neu bin und kommend von anderen Programmiersprachen es alles so unglaublich kompliziert für mich aussieht. So schneidet man z.B. das letzte Stringzeichen in D weg.

Code:
str = str[0..$-1];
Wie geht es in Delphi?

DieDolly 19. Feb 2020 07:03

AW: Auf den letzten char in einer Datei zugreifen
 
Mit Delete().
Wurde auf der ersten Seite doch verlinkt.

Von welcher Sprache kommst du?

KodeZwerg 19. Feb 2020 08:11

AW: Auf den letzten char in einer Datei zugreifen
 
Vielleicht hilft Dir das hier...
Delphi-Quellcode:
procedure SchreibeCSV;
var
  Inhalt: TStringList;
begin
  Inhalt := TStringList.Create;
  try
    Inhalt.Add('abc,123,xyz');
    Inhalt.SaveToFile('Dateiname.csv');
  finally
    Inhalt.Free;
  end;
end;
So könnte man eine frische Datei erzeugen.
Per Inhalt.Add was auch immer einfügen.
Per SaveToFile abspeichern, fertig.
Viel Spass.

dummzeuch 19. Feb 2020 08:33

AW: Auf den letzten char in einer Datei zugreifen
 
Zitat:

Zitat von kagi3624 (Beitrag 1457862)
Code:
str = str[0..$-1];
Wie geht es in Delphi?

Such' Dir was aus:

Delphi-Quellcode:
Delete(Str, Length(Str), 1);
str := LeftStr(Str, Length(Str)-1);
str := Copy(str, 1, Length(Str)-1);
SetLength(str, Length(Str)-1);
Und wenn es ein ShortString ist, geht auch:
Delphi-Quellcode:
Str[0] := AnsiChar(Byte(Str[0])-1);

Aber das will man nicht wirklich, zumal es bei normalen Strings zu Laufzeitfehlern führt.

Und ich habe bestimmt noch Möglichkeiten vergessen.

Jasocul 19. Feb 2020 09:42

AW: Auf den letzten char in einer Datei zugreifen
 
Zitat:

Zitat von kagi3624 (Beitrag 1457746)
wie kann ich auf den letzten Char in der Textdatei zugreifen um den eventuell zu löschen? Hintergrund: Ich schreibe in eine CSV Einträge und möchte das letzte Komma einfach löschen, ohne dass es in den EOF zugreift oder mir sonstwie um die Ohren fliegt.

Du erstellst also selbst diese CSV-Einträge.
Ich würde die CSV-Datei gleich korrekt füllen.
Dann sparst du dir das Gemurkse mit Datei einlesen, das letzte Zeichen löschen und die Datei neu speichern.

Vermutlich erstellst du in einer Schleife die Zeileneinträge. Für jeden Durchlauf der Schleife mit Trennzeichen. Da kannst du schon nach der Schleife das letzte Zeichen löschen oder beim letzten Durchlauf einfach das Trennzeichen weglassen.

Also Fehlerursache beheben und nicht hinterher daran rumbasteln.

freimatz 19. Feb 2020 10:42

AW: Auf den letzten char in einer Datei zugreifen
 
Zitat:

Zitat von kagi3624 (Beitrag 1457800)
Zitat:

Zitat von freimatz (Beitrag 1457798)
Wie kommst Du drauf, dass es sonst bei 0 anfängt? Was ist bei dir "sonst"?

Arrays?

Da kommt es darauf an welche. Hier nicht:
Delphi-Quellcode:
var
  MachineDimensions: Array [1..3] of aVectorT;
Und hier ist das erste nicht mal eine Zahl
Delphi-Quellcode:
var
  dateFormatsLongC: array [dateFormatET] of string;
Dagegen dynamische Array fangen immer bei 0 an, die verwende ich sehr selten.

himitsu 19. Feb 2020 11:28

AW: Auf den letzten char in einer Datei zugreifen
 
In mobilen Anwendungen (NextGen-Compiler) und in den neuen StringHelpern werden die Chars in den String ab 0 gerechnet.
Bei PChar der Offset sowieso schon immer mit 0.

PS: Weil der alte ShortString als im ersten Byte (0) die stehen Länge hat, fingen die Chars nunmal erst bei 1 an
und daher wurde im Pascal/Delphi dann auch die neueren LongStrings mit 1 begonnen, auch wenn dort nun das erste Zeichen intern auf Position 0 seht. (und die Verwaltungsdaten mit negativem Offset vor den Chars)

Statische arrays dind frei, in der Definition, aber ja, ei dynamischen Arrays fängt es bei null an.
Aber variante Arrays gäbe es auch noch und die sind auch komplett frei. (Typ Variant)

freimatz 19. Feb 2020 11:40

AW: Auf den letzten char in einer Datei zugreifen
 
Und am Besten man verlässt sich auf nichts und verwendet dann z.B. Low() - geht das bei String überhaupt?

himitsu 19. Feb 2020 16:35

AW: Auf den letzten char in einer Datei zugreifen
 
Zitat:

Zitat von freimatz (Beitrag 1457892)
Und am Besten man verlässt sich auf nichts und verwendet dann z.B. Low() - geht das bei String überhaupt?

Ja, aber im XE ging
Delphi-Quellcode:
Low(string)
noch nicht ... wollte ich vor Kurzem mal verwenden. :oops:

Und ja, verlassen besser nicht, denn wer seine geliebte 1 nicht verlieren will, der kann
Delphi-Quellcode:
{$ZEROBASEDSTRINGS OFF}
.
http://docwiki.embarcadero.com/RADSt...trings_(Delphi)


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:02 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