Zeile in einer Datei löschen

Gast #3579712
Lesenswert?

Hallo,
ich habe eine Frage wie kann man Zeilenweise eine Datei auslesen.
Ich möchte immer die letzte Zeile=Morgen löschen.
FILE *streamf;
streamf = fopen( szDatei, "a" );
if( streamf  == NULL )
{
  printf("--> Datei nicht vorhanden <--\n");
}
else
{
  printf("--> Datei nicht vorhanden <--\n");
}


Die Datei Test.txt sieht so aus:

Was
isst
Du

Morgen

Ich habe mit der Funktion fseek probiert aber geht nicht. Kann jemanden 
mir Hinweise geben.
Danke euch
#3579729
Lesenswert?

papy schrieb:
> Hallo,
> ich habe eine Frage wie kann man Zeilenweise eine Datei auslesen.

zb mit fgets. Oder mit getline

Sagt denn dein C-Lehrbuch nichts zum Thema "zeilenweises Lesen einer 
Textdatei". Das kann ich mir ehrlich gesagt kaum vorstellen. Denn gerade 
das ist eigentlich eine der Grundfertigkeiten, die man im Umgang mit 
Files lernen muss. Entsprechend großen Umfang sollte dieser Themenkreis 
eigentlich in den meisten Büchern einnehmen.

> Ich möchte immer die letzte Zeile=Morgen löschen.

Das Problem ist ganz einfach, dass (ausser wenn alle Zeilen wirklich 
gleich lang sind) niemand weiß, wo genau im File eigentlich die letzte 
Zeile anfängt.


> Ich habe mit der Funktion fseek probiert aber geht nicht. Kann jemanden
> mir Hinweise geben.

fseek würde schon gehen. Aber nicht so, wie du dir das vorstellst.
Mit fseek kann man nur das Ende der Datei finden. Aber niemand hindert 
dich daran, vom Dateiende dann mittels fseek dich zeichenweise 
vorzutasten, bis du auf den vorletzten \n stösst. Ein Zeichen danach 
beginnt dann die letzte Zeile.


Da du allerdings von 'letzte Zeile löschen' gesprochen hast, wird das so 
überhaupt nichts. Denn du kannst nicht einfach eine Zeile aus einer 
Datei löschen. Was du aber tun kannst: du kannst die ganze Datei auf 
eine neue Datei zeilenweise umkopieren, wobei du dann die letzte Zeile 
nicht mitkopierst. Wenn die Umkopieraktion abgeschlossen ist, wird die 
Original-Datei gelöscht, die jetzt kürzere Hilfsdatei auf den Namen der 
Originaldatei umbenannt und für den Benutzer sieht es so aus, als ob die 
letzte Zeile aus der Datei gelöscht worden wäre.
#3579794
Lesenswert?

Karl Heinz schrieb:
> Quack schrieb:
>
>> Am Ende Etwas loeschen geht auch in Ansi-C, da muss man nicht mit dem
>> Holzhammer ran.
>
>
> Ich lern gern was dazu.
> Mit welcher Funktion?

Hier ist die Auswahl an Funktionen aus C99

remove
rename
tmpfile
tmpname
fclose
fflush
fopen
freopen
setbuf
setvbuf
fprintf und Konsorten
fscanf und Konsorten
fgetc
fgets
fputc und Konsorten
fputs
getc und Konsorten
ungetc
fread
fwrite
fgetpos
fseek
fsetpos
ftell
rewind
clearerror
feof
ferror
perror

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1539.pdf
Abschnitt 7.21

Ich sehe ehrlich gesagt nicht, mit welcher Funktion man erreichen 
könnte, das in einem File etwas abgeschnitten wird.
Aber vielleicht irre ich mich oder in C11 ist noch was dazu gekommen, 
was mich eigentlich ein wenig wundern würde, denn das Konzept von C 
lautet ja eigentlich alle I/O Systeme (und dazu gehören Magnetbänder 
genauso wie Terminals oder Files) als Stream zu handhaben und einen 
Bogen um alles irgendwie File- oder Filesystemspezifische zu machen.
Gast #3579820
Lesenswert?

Hallo,

vielleicht drücke ich mich falsch aus.
Ich möchte mit Hilfe der Funktion.
streamf = fopen( szDatei, "a" ); mehrmals Werte in einer Datei 
schreiben, Hauptsache, dass die Werte immer sich vor der letzten Zeilen 
sich befinden.
Ich habe auch remove probiert aber geht nicht.
Gast #3579828
Lesenswert?

Entschuldigung, ich dachte an Posix (truncate/ftruncate) und habe Ansi-C 
geschrieben. Regt euch wieder ab, ihr seid ja wie die Geier. Aber das 
ist ja hier der uebliche Stil - lieber mit viel Aufwand rumkotzen als 
mit wenig Aufwand helfen.

papy: Du drueckst dich sehr unverstaendlich aus. Einfuegen geht nicht, 
aber wahrscheinlich wolltest du das auch nicht. Mach mal ein 
ordentliches Beispiel.
#3579871
Lesenswert?

Quack schrieb:
> Entschuldigung, ich dachte an Posix (truncate/ftruncate)

Das dacht ich mir schon, dass du Posix meinst und Ansi schreibst.

> geschrieben. Regt euch wieder ab, ihr seid ja wie die Geier. Aber das
> ist ja hier der uebliche Stil - lieber mit viel Aufwand rumkotzen als
> mit wenig Aufwand helfen.

Und wo war da jetzt deine Hilfe?
Ich hab ihm wenigstens das Kochrezept gegeben, mit dem er nur mit ANSI-C 
weiter kommt.

> papy: Du drueckst dich sehr unverstaendlich aus. Einfuegen geht nicht,

Womit wir wieder bei der Methode:
Manipuliere den Fileinhalt während eines Umkopier-Vorganges wären.

Es hat schon seinen Sinn, wenn ich ihm zuerst mal die generischen Ansi 
Funktionalitäten versuche beizubringen.
#3579889
Lesenswert?

Quack schrieb:
> Entschuldigung, ich dachte an Posix (truncate/ftruncate) und habe Ansi-C
> geschrieben. Regt euch wieder ab, ihr seid ja wie die Geier. Aber das
> ist ja hier der uebliche Stil - lieber mit viel Aufwand rumkotzen als
> mit wenig Aufwand helfen.

Was soll jetzt der Scheiß?
Du hast NICHT geholfen, nur behauptet es würde gehen ohne zu sagen wie; 
Karl Heinz hat geholfen, er hat freundlich gefragt, du "kotzt hier rum".

Jetzt musst du eingestehen, daß du auf dem falschen Dampfer warst und 
schon bist du der einzige der hier unfreundlich wird: "wie die Geier", 
"rumkotzen".

Hast du ein Problem damit einen Fehler zuzugeben? Das was du mit 
"üblicher Stil" bezeichnet bist du gerade selbst.
#3579899
Lesenswert?

papy schrieb:
> Beim zweiten Durchlauf des Programms, ist das xml Format falsh.

Wie wird das XML erzeugt? Das falsche XML am Ende durch ein Löschen der 
"letzten Zeile" korrigieren zu wollen ist bestimmt nicht der richtige 
Ansatz.
Hier ist der XML Generator fehlerhaft.

XML parsen oder gar generieren ist sicher keine Anfängerarbeit. Da 
sollten -sorry to say- die Grundlagen schon ordentlich sitzen.
Und dann nimmt man dazu eher eine fertige Parser-Bibliothek.
Gast #3579903
Lesenswert?

papy schrieb:
> Hallo,
> ertsmals entschuldige ich mich für meine Deutschkenntnisse.
> Anbei habt Ihr das Beispiel, was ich am ende erreichen will.
> Beim zweiten Durchlauf des Programms, ist das xml Format falsh

Hallo papy,

wenn Du xml erzeugen möchtest, dann verwende der Einfachheit halber eine 
XML-Library.

Dieses Datei-reinschreiben-löschen-Gemurkse is nix vernünfigens. Das 
fällt Dir immer wieder auf die Nase.

Frank
Gast #3579904
Lesenswert?

papy schrieb:
> Hallo,
> ertsmals entschuldige ich mich für meine Deutschkenntnisse.
> Anbei habt Ihr das Beispiel, was ich am ende erreichen will.
> Beim zweiten Durchlauf des Programms, ist das xml Format falsh.

Wenn Du schon XML hast warum dann in C ?
Es gibt doch extra XSLT um XML zu parsen ?
Oder willst Du ein reines Textfile mit XML Tags verknüpfen ?
Setz Dich mal hin und schreibe Dir detailliert auf was Du eiegentlich 
machen willst/mußt und versuche das dann hier nochmal zu erklären.
Dann und NUR dann kann Dir auch geholfen werden !
#3579909
Lesenswert?

Frank schrieb:

> wenn Du xml erzeugen möchtest, dann verwende der Einfachheit halber eine
> XML-Library.

Full-Ack

Denn das File mit den genannten Ausgangsdaten könnte ja (bei gleichem 
Inhalt!) auch so aussehen
1
<?xml version='1.0' encoding='ISO-8859-1'?> 
2
<Morgen> <esse1> <ich> Orange </ich> </esse1> </Morgen>

und dann ist es im wahrsten Sinne Essig mit der Technik "suche die 
vorletzte Zeile und hänge einen neuen XML Abschnitt da rein.
Um XML sinnvoll zu manipulieren darf man vor allen Dingen eines nicht: 
Naiv das File als eine Ansammlung von Zeilen ansehen. Das geht mehr als 
ganz schnell in die Hose.


kopfkratz hat ja schon XSLT erwähnt.

Die Frage ist jetzt eigentlich die:
Worum gehts eigentlich?
Gehts um Manipulation eines XML Files. Dann ist dieser naive Ansatz kein 
guter
Oder gehts darum, Filehandling zu lernen. Dann war die 'Wahl' von XML 
als Lernobjekt keine gute Wahl.
#3579922
Lesenswert?

papy schrieb:
> Von welcher Bibiothek redet ihr?

Von Bibliotheken, mit denen man ein XML File lädt.
Da gibt es 2 grundsätzlich verschiedene Ansätze
* Callbacks on the Fly. D.h. der Parser ruft nach jedem erkannten XML 
'Token' eine angegebene Funktion auf, damit die die Daten bearbeitet
* oder den DOM Ansatz, in dem der Parser den Fileinhalt komplett in den 
Speicher einliest und man dann in diesem sich so ergebenden Baum 
Manipulationen macht.


In deinem Fall, in dem es offenbar darum geht, an eine in XML 
gespeicherte Datenstruktur ergänzungen anzubringen, würde sich der DOM 
Ansatz anbieten.

Das Prinzip ist dann:
Parser soll das XML lesen
Im Baum wird dann die zusätzliche Information, dass du morgen nicht nur 
Orangen sondern auch Bananen essen willst eingehängt und der Parser 
kriegt dann den Auftrag ein neues XML File daraus zu erstellen.
#3579923
Lesenswert?

papy schrieb:
> ich habe bis jetzt nur mit  sprintf bearbeitet um die enzeilne Zeile in
> der xml zu schreiben.

Die Frage ist tiefgreifender. Sie lautet

Worum gehts eigentlich?
Gehts um Manipulation eines XML Files. Dann ist dieser naive Ansatz kein 
guter
Oder gehts darum, Filehandling zu lernen. Dann war die 'Wahl' von XML 
als Lernobjekt keine gute Wahl.
#3579941
Lesenswert?

papy schrieb:
> ch habe bis jetzt nur mit  sprintf bearbeitet um die enzeilne Zeile in
> der xml zu schreiben.

Eine XML Datei hat KEINE Zeilen.
Im Extremfall hat die keinen einzigen Zeilenumbruch wenn die Daten in 
dem XML keinen Zeilenumbruch haben.
Auch ist das per Definition keine Text-Datei, sondern eine Binärdatei. 
Nur dar erste Token definiert als Wichtigstes auch den Zeichensatz, der 
zu verwenden ist um den Rest der Datei dann als Text zu interpretieren.
Oft genug ist das dann UTF-8.
#3579954
Lesenswert?

papy schrieb:
> Hallo Karl,
> ich verstehe nicht die Frage.

Das was ich versuche rauszufinden, ist eigentlich das

Wie sehr übernimmst du dich momentan und muss das so sein, weil du dich 
auf etwas versteift hast, was du ganz offensichtlich noch bei weitem 
nicht beherrscht.

Die Frage lautet: Ist XML jetzt nur zufällig da ins Spiel gekommen, weil 
du mal irgendwo XML gehört hast, oder steckt da eine Notwendigkeit 
dahinter, dass du XML bearbeiten können musst.

WEnn es sich nur zufällig ergeben hat, dann such dir was anderes aus, 
nur nicht XML

Wenn du aber XML als unabdingbare Vorgabe hast, dann gehst du mit den 
falschen WErkzeugen an die Sache ran.


Beides zusammen geht noch nicht. Dazu bist du noch zu schwach. 
Irgendwann wird es mal soweit sein, dass du XML sinnvoll und richtig mit 
reinem C bearbeiten kannst (zumindest prinzipiell), aber im Moment ist 
das noch um ein paar Schuhnummern zu groß für dich. Da müssen erst mal 
ein paar zig andere Dateibehandlungen und Techniken sitzen.

Jetzt klarer?
#3579997
Lesenswert?

Udo Schmitt schrieb:
> Wolfgang schrieb:
>> Und wehe, wehe, wenn die letzte Zeile nicht mit einem \n abgeschlossen
>> ist.
>
> Ja und? Was ist dann? Siehe mein Beitrag oben.
> Eine XML Datei ist erst mal Binär und braucht KEINEN Zeilenumbruch.

Wolfgang hat sich auf die Technik bezogen, die letzte Zeile in einer 
Datei zu finden, die ich weiter oben mal angeschnitten habe.
Zu diesem Zeitpunkt war von XML noch keine Rede.
#3580006
Lesenswert?

papy schrieb:
> Gut!lassen wir dann xml Format weg.
> wie finde ich die letzte Zeile in dieser Datei und diese Zeile komplet
> löschen.
>
> Text.txt
> esse
> Orange
> Morgen

Auch wenn QUack da wieder was degegen haben wird.

Die allgemeine Form wird so aussehen
1
  char line[80];
2

3
  input = fopen ....
4
  output = fopen ....
5

6
  while( fgets( line, 80, input ) )
7
  {
8
     if( irgendwas mit line )
9
       veändere line
10

11
     fputs( line, output );
12
  }
13

14
  fclose( input );
15
  fclose( output );
16

17
  rename( ... );
18
}

damit kannst du jegliche Manipulation an einem File machen, nicht nur 
die letzte Zeile löschen. Die letzte Zeile löschen ist ein Sonderfall, 
den man unter Umständen etwas anders durchführen kann (mit dem bereits 
angesprochenen truncate nachdem man den Beginn der letzten Zeile 
gefunden hat), während diese Variante das allgemeinste Fall ist, bei dem 
man den Inhalt einer Datei manipuliert, während man ihn auf eine neue 
Datei schreibt.
Zum Beispiel: Schreibst du eine Zeile NICHT wieder auf output, dann ist 
sie offensichtlich dort nicht vorhanden und somit gelöscht.
AUfbauend auf diesem grundsätzlichen Muster, kannst du alle 
Dateimanipulationen in Textdateien machen, die zeilenweise organisiert 
sind.

Ein File ist nun mal ein sequentielles Medium, in dem man nicht wahlfrei 
einfügen oder löschen kann. Vergleichbar einem Tonband mit Musikstücken. 
Du kannst auf einem Tonband nicht einfach ein Musikstück zwischen zwei 
anderen rausnehmen oder einfügen. Wenn du das willst, dann muss das 
Tonband hinter dem zu bearbeitendem Stück neu gemacht werden. Allenfalls 
beim letzten Stück kann man das ein bischen vereinfachen. Aber den Fall 
hat man so oft dann auch wieder nicht. Bei dir ist das ja auch nur ein 
Sonderfall. Denn spätestens dann, wenn in der Datei steht, was du ißt 
und was deine Freundin ißt, geht diese Technik dann grauslich den Bach 
runter, weil sie nicht verallgemeinert.

Um in
1
ich
2
esse
3
Orange Morgen
4
Andrea
5
esse
6
Banane Morgen
zusätzlich zu deinen Orangen noch zu vermerken, dass du Müsli essen 
wirst, kommst du mit dem löschen der letzten Zeile nicht mehr weiter.
Gast #3580070
Lesenswert?

papy schrieb:
> Gut!lassen wir dann xml Format weg.
> wie finde ich die letzte Zeile in dieser Datei und diese Zeile komplet
> löschen.
>
> Text.txt
> esse
> Orange
> Morgen

Also mal wieder kein C Buch vorhanden m(
Einmal gesucht findet z.B. das unter den ersten zehn Treffern:
http://cplus.about.com/od/learningc/ss/files.htm
KarlHeinz hat ja schon Pseudocode geliefert wie das am sinnvollsten 
geht, Datei in internen Puffer einlesen, parsen, ändern und 
zurückschreiben.
Wie erkennst Du denn Dein Zielwort überhaupt ?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren