Forum: Compiler & IDEs Zeile in einer Datei löschen


von papy (Gast)


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

von Quack (Gast)


Lesenswert?

File oeffnen, seek bis zum Ende, rueckwaerts Zeichen lesen bis das 
Zeilenende gefunden ist, dann einfach Filegroesse neu setzen.

von Karl H. (kbuchegg)


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.

: Bearbeitet durch User
von Quack (Gast)


Lesenswert?

Karl Heinz schrieb:

> Denn du kannst nicht einfach eine Zeile aus einer Datei löschen.

Am Ende Etwas loeschen geht auch in Ansi-C, da muss man nicht mit dem 
Holzhammer ran.

von Karl H. (kbuchegg)


Lesenswert?

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?

von papy (Gast)


Lesenswert?

ich habe folgendes gemacht:

   if ( fgets (acTeststring , 100 , streamf) != NULL )
    {
       printf("--> Ende der Tadei gefunden <--\n" );

    }
Die Frage ist? wie lösche ich dann diese Zeile

von Karl H. (kbuchegg)


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.

: Bearbeitet durch User
von Michael R. (Firma: Brainit GmbH) (fisa)


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?

ich häng mich an die frage gleich an, weil das möchte ich auch lernen...

von papy (Gast)


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.

von Quack (Gast)


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.

von Bitflüsterer (Gast)


Lesenswert?

Hast Du gelesen Karl Heinz? Du bist ein Geier. ROFL

>http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1539.pdf
Oh. Danke sehr.

von Karl H. (kbuchegg)


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.

: Bearbeitet durch User
von papy (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Udo S. (urschmitt)


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.

von Udo S. (urschmitt)


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.

von Frank (Gast)


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

von kopfkratzer (Gast)


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 !

von Karl H. (kbuchegg)


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.

: Bearbeitet durch User
von papy (Gast)


Lesenswert?

Von welcher Bibiothek redet ihr?

von papy (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


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.

von papy (Gast)


Lesenswert?

Hallo Karl,
ich verstehe nicht die Frage.
Ich habe erstmals meine xml file mit fopen geöffnet und dann 
reingeschrieben.
Es geht nur um Werte(String)in der xml Datei einzufügen.

von Udo S. (urschmitt)


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.

von Udo S. (urschmitt)


Lesenswert?

papy schrieb:
> Es geht nur um Werte(String)in der xml Datei einzufügen.

Was ist dein eigentliches Problem?
Hausaufgabe?
Dann poste hier bitte die komplette Aufgabe und deinen Lösungsansatz.

von papy (Gast)


Lesenswert?

ich bin auch auf diese Seite gestoßen:
http://www.foxplanet.de/xmlstorage/xmlstorage-de.html
Was ist in storage.xml drin ist, weiß ich nicht.
Ich weiss nicht, ob es schon fertige Bibliothek in c gibt, die diese 
Struktur einer XMlvereinfacht.

von Karl H. (kbuchegg)


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?

: Bearbeitet durch User
von Udo S. (urschmitt)


Lesenswert?

Karl Heinz schrieb:
> 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 ich mir das Beispiel anschaue, dann fehlt auch noch das Verständnis 
wie XML überhaupt strukturiert.

von Wolfgang (Gast)


Lesenswert?

Karl Heinz schrieb:
> 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.

Und wehe, wehe, wenn die letzte Zeile nicht mit einem \n abgeschlossen 
ist.

von Udo S. (urschmitt)


Lesenswert?

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.

von Karl H. (kbuchegg)


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.

: Bearbeitet durch User
von papy (Gast)


Lesenswert?

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

von Quack (Gast)


Lesenswert?

Karl Heinz schrieb:
> Und wo war da jetzt deine Hilfe?

Es steht da, mit welcher Funktion es geht. Hast du selbst zitiert.

von Karl H. (kbuchegg)


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.

: Bearbeitet durch User
von kopfkratzer (Gast)


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 ?

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Karl Heinz,

ich hab dich ja schon vor Monaten mal gefragt, aber leider keine Antwort 
erhalten :-(

Wo nimmst du deine Geduld her?

von ich (Gast)


Lesenswert?

Michael Reinelt schrieb:
> Karl Heinz,
>
> ich hab dich ja schon vor Monaten mal gefragt, aber leider keine Antwort
> erhalten :-(
>
> Wo nimmst du deine Geduld her?

So was geht nur, in dem man selbst eine innere Ruhe hat.

von Karl H. (kbuchegg)


Lesenswert?

Michael Reinelt schrieb:
> Karl Heinz,
>
> ich hab dich ja schon vor Monaten mal gefragt, aber leider keine Antwort
> erhalten :-(
>
> Wo nimmst du deine Geduld her?

Keine Ahnung.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.