Textdatei auslesen und erste Zeile löschen?

Anfängerfragen zum Programmieren mit PureBasic.
tim
Beiträge: 21
Registriert: 05.12.2010 20:49

Textdatei auslesen und erste Zeile löschen?

Beitrag von tim »

Hallo,

mir fällt leider keine sinnvolle Lösung für folgendes Problem ein:
Ich möchte die erste Zeile einer Textdatei auslesen, dann die
erste Zeile löschen und den Rest "nach oben rutschen lassen".

Textdatei vorher:

Code: Alles auswählen

aaaaa
bbbbb
ccccc
ddddd
eeeee
.....

Textdatei nachher:

Code: Alles auswählen

bbbbb
ccccc
ddddd
eeeee
.....

Auf diese Weise möchte ich die Textdatei gern, Schritt für Schritt, abarbeiten.


Würde mich sehr über eine kleine Hilfe freuen!


Gruß
Tim
Drago
Beiträge: 148
Registriert: 02.02.2010 18:22
Computerausstattung: Win XP SP3, AMD Sempron (MMX) 1.2 GHz, 512 MB, Nvidia GeForce FX 5200, 128 MB, DirectX 9.0c
Wohnort: Westerwald

Re: Textdatei auslesen und erste Zeile löschen?

Beitrag von Drago »

Guten Morgen die Dame.. :D

Ich kenne mich mit solchen Dingen nicht besonders aus, ber mir ist dazu eine Idee gekommen.
In der Hilfe steht für die ASCII Zeichen..
13 Wagenrücklauf. Das Zeichen, welches den Kopf einer Schreibmaschine oder eines Druckers auffordert, sich zurück zum Anfang einer Zeile zu bewegen. Normalerweise verwendet als das - oder Teil des - 'End of Line' (Ende der Zeile) Zeichens.
Teste beim Einlesen einfach auf diesen ASCII - Wert, dann müsste es doch klappen..

LG Drago
Drago
Beiträge: 148
Registriert: 02.02.2010 18:22
Computerausstattung: Win XP SP3, AMD Sempron (MMX) 1.2 GHz, 512 MB, Nvidia GeForce FX 5200, 128 MB, DirectX 9.0c
Wohnort: Westerwald

Re: Textdatei auslesen und erste Zeile löschen?

Beitrag von Drago »

Syntax

Text$ = ReadString(#Datei [, Flags])
Beschreibung

Liest einen String aus einer Datei bis ein 'End Of Line' (EOF - in Deutsch: "Ende der Zeile") Zeichen gefunden wird (Unix- und DOS-Dateiformate werden unterstützt).
Oder so etwas benutzen, je nachdem, wie du deinen Text ausliest..
Ohne Code, schwer....
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Re: Textdatei auslesen und erste Zeile löschen?

Beitrag von Falko »

Versuchs mal hiermit, indem eine Kopie von deiner Textdatei gemacht wird,
und diese dann Zeile für Zeile ohne der ersten in deine Textdatei neu
geschrieben wird.

Code: Alles auswählen

Procedure.s EraseFirstText(MyDat.s)
  Protected VirtDat.s="MyText.$$$",ErsteZeile.s
  If FileSize(MyDat)=>0
    If CopyFile(MyDat,VirtDat)
       OpenFile(0,VirtDat)
       CreateFile(1,MyDat)
       ReadFile(0,VirtDat)
       ErsteZeile=ReadString(0)
       FileSeek(0,Len(ErsteZeile))
       WriteString(1,ReadString(0))
       While Eof(0)=0
         WriteStringN(1,ReadString(0,#PB_Ascii))
       Wend
       CloseFile(1)
       CloseFile(0)
       DeleteFile(VirtDat)
     Else
       MessageRequester("Achtung!","Die Datei konnte nicht kopiert werden")
     EndIf
  Else
    MessageRequester("Achtung","Ist die Datei vorhanden und nicht leer?")
   EndIf
   ProcedureReturn ErsteZeile
EndProcedure



MessageRequester("1.Zeile ausgeben",EraseFirstText("MyDat.txt"))
Gruß,
Falko
Bild
Win11 Pro 64-Bit, PB_6.11b1
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Textdatei auslesen und erste Zeile löschen?

Beitrag von ts-soft »

Hier eine etwas einfachere und schnellere Lösung:

Code: Alles auswählen

EnableExplicit

Define FF, Format, File.s = "d:\wichtig.txt" ; <- hier anpassen
Define length, *mem, pos

FF = OpenFile(#PB_Any, File)
If FF
  Format = ReadStringFormat(FF)                         ; Stringformat sichern.
  length = Lof(FF)                                      ; länge ermitteln.
  *mem = AllocateMemory(length)                         ; Speicher reservieren.
  If *mem
    ReadData(FF, *mem, length)                          ; Daten in den Speicher lesen.
    pos = FindString(PeekS(*mem, -1, Format), #LF$)     ; erstes Zeilenende Zeichen suchen.
    If pos
      FileSeek(FF, 0)                                   ; wenn gefunden, zurück an den Anfang.
      WriteStringFormat(FF, Format)                     ; BOM schreiben.
      WriteData(FF, *mem + pos, length - pos)           ; Daten ab gefundener pos schreiben.
      TruncateFile(FF)                                  ; Rest vom Orginal abschneiden.
    EndIf
    FreeMemory(*mem)                                    ; Speicher freigeben.
  EndIf
  
  ;ab hier neue Zeilen Schreiben.
  ;WriteStringN(FF, "bla", Format)
  CloseFile(FF)
EndIf
Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Andreas21
Beiträge: 390
Registriert: 30.08.2004 09:05
Computerausstattung: Desktop
Windows 10 Pro x64
CPU: AMD Ryzen 5 2600 3.40 GHz
Ram: 16GB RAM
Grafik: NVIDA Geforce 1060
PB: 5.72 X86/X64
Wohnort: Heidelberg

Re: Textdatei auslesen und erste Zeile löschen?

Beitrag von Andreas21 »

So würde ich es machen.

Code: Alles auswählen

EnableExplicit

Define FF, Format, File.s = "wichtig.txt" ; <- hier anpassen
Define length, *mem, tmp.s

FF = OpenFile(#PB_Any, File)
If FF
  Format = ReadStringFormat(FF)                       ; Stringformat sichern.
  length = Lof(FF)                                    ; länge ermitteln.
  tmp = ReadString(FF, Format)                        ; Die erste Zeile einlesen
  length = length - Loc(FF)                           ; Die Aktuelle Position von der gesamtlänge abziehen.
  *mem = AllocateMemory(length)                       ; Speicher reservieren.
  If *mem
    ReadData(FF, *mem, length)                        ; Daten in den Speicher lesen.
    FileSeek(FF, 0)                                   ; wenn gefunden, zurück an den Anfang.
    WriteStringFormat(FF, Format)                     ; BOM schreiben.
    WriteData(FF, *mem, length)                       ; Daten ab gefundener pos schreiben.
    TruncateFile(FF)                                  ; Rest vom Orginal abschneiden.
    FreeMemory(*mem)                                  ; Speicher freigeben.
  EndIf
 
  ;ab hier neue Zeilen Schreiben.
  ;WriteStringN(FF, "bla", Format)
  CloseFile(FF)
EndIf
Windows 10 x64 Pro - PB 5.61 X64 / x32 - PB 4.6 x32
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Textdatei auslesen und erste Zeile löschen?

Beitrag von ts-soft »

@Andreas21

Warum liest Du die erste Zeile mit dem langsamen ReadString aus?
#LF$ ist in jeder Textdatei als Zeilenende vorhanden, egal ob
Windows oder Linux. Wenn #CRLF$ ändert nichts an der Zuverlässigkeit
meiner Routine, lediglich bei älteren Mac-Systemen könnte es versagen,
da nur #CR$ vorhanden.

Ansonsten ist es auch mehr Geschmackssache :wink:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Re: Textdatei auslesen und erste Zeile löschen?

Beitrag von Falko »

Dann nehmen wir auch
nochmal LinkedList() hinzu :wink:
[Edit] Auswahl der jeweilig zu löschenden Zeile ist hiermit möglich.
Auch im nachfolgenden Beitrag von TS-Soft beschriebenen ASCII-Formaten,
habe ich das auch im Code hinzugefügt. Also UTF-8 ist möglich :wink:
[/Edit]

Code: Alles auswählen

EnableExplicit
Procedure.s EraseTextLines(MyDat.s,line.l)
  Protected Result.s,Format
  NewList TLine.s()
  If FileSize(MyDat)=>0
    ;Einlesen der kompletten Textdatei in den Speicher
    OpenFile(0,MyDat)
    Format=ReadStringFormat(0)
    While Eof(0)=0 
      AddElement(TLine())
      TLine()=ReadString(0,Format)
    Wend
    CloseFile(0)
    ;Schreiben aus dem geänderten Speicherinhalt wieder in die Datei
    CreateFile(0,MyDat)
    SelectElement(TLine(),line-1)
    Result=TLine()
    DeleteElement(TLine())
    ResetList(TLine())
    While NextElement(TLine()) 
      WriteStringN(0,TLine(),Format)
    Wend
    CloseFile(0)
   Else
     MessageRequester("Achtung","Ist die Datei vorhanden und nicht leer?")
   EndIf
   ProcedureReturn Result
EndProcedure

MessageRequester("Gelöschte Zeile",EraseTextLines("MyText.txt",1))
Gruß
Falko
Bild
Win11 Pro 64-Bit, PB_6.11b1
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Textdatei auslesen und erste Zeile löschen?

Beitrag von ts-soft »

@Falko

Naja, Textformat wird nicht berücksichtigt (funktioniert nur mit ASCII-Texten, die es kaum noch gibt,
heutzutage sind die meisten Textdateien in UTF-8 codiert), und auch langsamer, was bei kleineren
Dateien natürlich keine Rolle spielt. Vorteile kann ich keine erkennen, ganz im Gegenteil :wink:

// edit
Hab meinen Code nochmals optimiert. Hab es in eine Procedure gepackt und jetzt wird auch
berücksichtigt, wenn die letzte Zeile kein EOL (EndOfLine) enthält.

Code: Alles auswählen

EnableExplicit

Procedure RemoveFirstLine(File, EOL.s = #LF$)
  Protected Format, length.q, *mem, pos.q
 
  If IsFile(File)
    FileSeek(File, 0)
    Format = ReadStringFormat(File)
    length = Lof(File)
    If length
      *mem = AllocateMemory(length)
      ReadData(File, *mem, length)                          ; Daten in den Speicher lesen.
      pos = FindString(PeekS(*mem, -1, Format), EOL)      ; erstes Zeilenende Zeichen suchen.
      If pos
        WriteStringFormat(File, Format)                     ; BOM schreiben.
        WriteData(File, *mem + pos, length - pos)           ; Daten ab gefundener pos schreiben.
        TruncateFile(File)                                  ; Rest vom Orginal abschneiden.
        If PeekS(*mem + length - Len(EOL), Len(EOL), Format) <> EOL
          WriteStringN(File, "", Format)
        EndIf
      EndIf
      FreeMemory(*mem) 
    EndIf  
  EndIf
  ProcedureReturn Format
EndProcedure

Define Format, FF = OpenFile(#PB_Any, "wichtig.txt")
If FF
  Format = RemoveFirstLine(FF)
  WriteStringN(FF, "Ich bin die neue letzte Zeile", Format)
  ; ...
  CloseFile(FF)
EndIf
// edit
noch mal fehler beseitigt bei leerer Datei.
Zuletzt geändert von ts-soft am 23.03.2012 13:07, insgesamt 2-mal geändert.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: Textdatei auslesen und erste Zeile löschen?

Beitrag von CSHW89 »

ts-soft hat geschrieben:@Andreas21

Warum liest Du die erste Zeile mit dem langsamen ReadString aus?
#LF$ ist in jeder Textdatei als Zeilenende vorhanden, egal ob
Windows oder Linux. Wenn #CRLF$ ändert nichts an der Zuverlässigkeit
meiner Routine, lediglich bei älteren Mac-Systemen könnte es versagen,
da nur #CR$ vorhanden.

Ansonsten ist es auch mehr Geschmackssache :wink:
Naja, selbst wenn eine Datei richtig groß ist, spielt, glaube ich, EIN Aufruf von ReadString keine Rolle, zumal es dann auch sicherer ist, wie du schon sagt, falls das Zeilenende nur #CR$ ist.

@Andreas21, @ts-soft:
Ach ja, falls die Datei leer ist, gibts bei euch beiden ein Fehler, und wenn die Datei nur aus einer Zeile besteht (ohne Zeilenumbruch), gibts bei Andreas21 auch ein Fehler und bei ts-soft macht er nix, löscht also nicht die eine Zeile. Also wäre meine Lösung:

Code: Alles auswählen

EnableExplicit

Define FF, Format, File.s = "wichtig.txt" ; <- hier anpassen
Define length, *mem, tmp.s

FF = OpenFile(#PB_Any, File)
If FF
  Format = ReadStringFormat(FF)                       ; Stringformat sichern.
  length = Lof(FF)                                    ; länge ermitteln.
  tmp = ReadString(FF, Format)                        ; Die erste Zeile einlesen
  length = length - Loc(FF)                           ; Die Aktuelle Position von der gesamtlänge abziehen.
  If length
    *mem = AllocateMemory(length)                       ; Speicher reservieren.
    If *mem
      ReadData(FF, *mem, length)                        ; Daten in den Speicher lesen.
      FileSeek(FF, 0)                                   ; wenn gefunden, zurück an den Anfang.
      WriteStringFormat(FF, Format)                     ; BOM schreiben.
      WriteData(FF, *mem, length)                       ; Daten ab gefundener pos schreiben.
      TruncateFile(FF)                                  ; Rest vom Orginal abschneiden.
      FreeMemory(*mem)                                  ; Speicher freigeben.
    EndIf
  Else
    FileSeek(FF, 0)
    WriteStringFormat(FF, Format)
    TruncateFile(FF)
  EndIf
 
  ;ab hier neue Zeilen Schreiben.
  ;WriteStringN(FF, "bla", Format)
  CloseFile(FF)
EndIf
lg Kevin

Edit: edit von ts-soft zu spät gesehen :mrgreen:
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Antworten