Wie schneide ich eine Datei in C ab?

Lesezeit: 7 Minuten

Benutzeravatar von sofr
sofr

Ich verwende C, um einige Daten in eine Datei zu schreiben. Ich möchte den vorherigen Text in der Datei löschen, falls er länger war als das, was ich jetzt schreibe. Ich möchte die Größe der Datei verringern oder bis zum Ende abschneiden. Wie kann ich das machen?

Benutzeravatar von Jonathan Leffler
Jonathan Leffler

Wenn Sie den vorherigen Inhalt der Datei bis zu einer gewissen Länge beibehalten möchten (eine Länge größer als Null, die andere Antworten bereitstellen), stellt POSIX dies bereit truncate() und ftruncate() Funktionen für den Job.

#include <unistd.h>
int ftruncate(int fildes, off_t length);
int truncate(const char *path, off_t length);

Der Name gibt den Hauptzweck an – das Kürzen einer Datei. Wenn die angegebene Länge jedoch länger als die vorherige Länge ist, wächst die Datei (Nullauffüllung) auf die neue Größe an. Beachten Sie, dass ftruncate() arbeitet mit einem Dateideskriptor, nicht mit einem FILE *; Du könntest benutzen:

if (ftruncate(fileno(fp), new_length) != 0) ...error handling...

Sie sollten sich jedoch bewusst sein, dass das Mischen von Dateistreams (FILE *) und Dateideskriptor (int) kann der Zugriff auf eine einzige Datei zu Verwirrung führen – siehe die Kommentare zu einigen der Probleme. Dies sollte ein letzter Ausweg sein.

Es ist jedoch wahrscheinlich, dass für Ihre Zwecke das Abschneiden beim Öffnen alles ist, was Sie brauchen, und dafür werden die von anderen angegebenen Optionen ausreichen.


Für Windows gibt es eine Funktion SetEndOfFile() und eine verwandte Funktion SetFileValidData() Funktion, die eine ähnliche Aufgabe erledigen kann, aber eine andere Schnittstelle verwendet. Grundsätzlich suchen Sie, wo Sie das Dateiende setzen möchten, und rufen dann die Funktion auf.

Es gibt auch eine Funktion _chsize() wie in der Antwort von sofr dokumentiert.

  • Bemerkenswert ähnlich, Lance! Mindestens einer von uns hat die Informationen wahrscheinlich richtig verstanden. (Die Verwendung von soll in den neueren POSIX-Standards nicht notwendig sein; aus Sicherheitsgründen schadet es aber nicht.)

    – Jonathan Leffler

    17. Mai 2009 um 3:29 Uhr

  • Gibt es eine solche Funktion in C++ vs. 2003, die ich nicht finden konnte? Nichts davon hat geholfen, vielleicht habe ich etwas übersehen? Ich möchte die Datei nicht mit w öffnen, sondern die bereits geöffnete Datei verwenden

    – sofr

    17. Mai 2009 um 5:43 Uhr

  • Ich bin mir nicht sicher. Die meisten POSIX-Funktionen sind in MSVC verfügbar, aber Microsoft hat entschieden, dass ein Unterstrich am Anfang des Funktionsnamens stehen muss – daher _truncate() und _ftruncate(). Außerdem sind dies C-Funktionen, nicht C++; Möglicherweise müssen Sie es auf diese Weise nachverfolgen. In der MSVC 2008, die ich habe, finde ich keinen unistd.h-Header; Ich bin mir nicht sicher, ob es das in anderen Editionen gibt, oder ob ich einfach nicht an der richtigen Stelle gesucht habe.

    – Jonathan Leffler

    17. Mai 2009 um 14:48 Uhr

  • Ich bin mir ziemlich sicher (zumindest auf dem Mac), dass es nicht sicher ist, anzurufen ftruncate(file no(fp)) auf eine geöffnete Datei. Weder die internen Lese- noch Schreibpuffer von fp wird gespült. Anruf std::fflush bevor die Schreibpuffer geleert werden und std::freopen danach neu initialisieren fp

    – Sebastian

    28. Oktober 2015 um 14:44 Uhr

  • @Sebastian: Es gibt keine std::fflush oder std::freopen in C; Sie müssen dies mit einer anderen Sprache verwechseln – vermutlich C++. Es hängt davon ab, was Sie mit “nicht sicher” meinen. Sicher treten Sie sofort aus dem Wissen des Dateistroms heraus und führen Operationen hinter seinem Rücken durch. Nichts wird Puffer leeren; du solltest benutzen fflush(fp) vor Gebrauch ftruncate(fileno(fp)). Was als Nächstes passiert, hängt davon ab, wie Sie die Datei geöffnet haben, ob Sie den Dateistream vor dem nächsten Vorgang neu positionieren und von anderen Details. Auf der o/s-Ebene wurde die Datei jedoch abgeschnitten.

    – Jonathan Leffler

    28. Oktober 2015 um 15:37 Uhr

Benutzeravatar von sofr
sofr

In Windows-Systemen gibt es keinen Header <unistd.h> Sie können eine Datei jedoch mit abschneiden

 _chsize( fileno(f), size);

  • _chsize_s für 64 Bit: _chsize_s(_fileno(f), size);

    – Guri

    17. Juni 2011 um 22:41 Uhr


  • Die _fileno-Funktion hilft wirklich, wenn wir die FILE-Struktur verwenden

    – Karthi

    30. April 2014 um 2:33 Uhr

  • Ist das nicht eine reine MS-Windows-Funktion?!

    – Alexis Wilke

    16. März 2015 um 4:17 Uhr

  • @AlexisWilke Er sagte “In Windows-Systemen”; also ja, _chsize() ist eine reine Windows-Funktion.

    – Aaron Campbell

    7. Juli 2016 um 18:57 Uhr

  • fileno() ist standardisiert in POSIX. Microsofts „Abwertung“ ist bestenfalls merkwürdig.

    – Andreas Henle

    9. Januar 2017 um 14:23 Uhr

Benutzeravatar von pixelbeat
Pixelschlag

Das ist eine Funktion Ihres Betriebssystems. Die Standardmethode für POSIX ist:

open("file", O_TRUNC | O_WRONLY);

  • Dadurch wird die Datei auf eine Größe von 0 Byte gekürzt.

    – Chike

    1. August 2015 um 13:43 Uhr

  • Die Frage war eindeutig, die Datei auf eine bestimmte Größe zu kürzen/zu verkleinern.

    – Salchin

    5. August 2020 um 4:49 Uhr

  • Ich stimme zu, dass dies keine Antwort auf die Frage ist, sondern auf den Titel. Ich bin hierher gekommen, um zu versuchen, auf 0 Bytes zu kürzen, und der Titel stimmt mit meiner Suche bei Google überein, also ist eine +1-Stimme gültig, denke ich, da er einen Standard erwähnt.

    – Enrique Rene

    18. August 2020 um 1:58 Uhr


  • Denken Sie daran, #include #include #include einzuschließen

    – Jonathan Ben-Avraham

    8. Februar 2021 um 11:49 Uhr


  • Wenn Sie nicht möchten, dass es danach geöffnet wird, verwenden Sie truncate("file", 0); um seine Länge auf Null zu setzen. Es ist eine POSIX-Funktion. Aber ja, wenn Sie möchten, dass die Datei danach wie eine Shell geöffnet wird foo > file Umleitung würde, das ist, was Sie wollen.

    – Peter Cordes

    6. April um 7:23


Wenn dies unter einer UNIX-Variante ausgeführt werden soll, sollten diese APIs verfügbar sein:

   #include <unistd.h>
   #include <sys/types.h>

   int truncate(const char *path, off_t length);
   int ftruncate(int fd, off_t length);

Laut “man truncate” auf meiner Linux-Box sind diese POSIX-konform. Beachten Sie, dass diese Aufrufe die Größe der Datei tatsächlich erhöhen (!), wenn Sie eine Länge übergeben, die größer als die aktuelle Länge ist.

Benutzeravatar von Danny Battison
Danny Battison

Ah, Sie haben Ihren Beitrag bearbeitet, Sie verwenden C. Wenn Sie die Datei öffnen, öffnen Sie sie mit dem Modus “w +” wie folgt, und sie wird zum Schreiben abgeschnitten:

FILE* f = fopen("C:\\gabehabe.txt", "w+");
fclose(file);

Um eine Datei in C++ zu kürzen, können Sie einfach ein Ofstream-Objekt für die Datei erstellen, indem Sie verwenden ios_base::trunc als Dateimodus zum Abschneiden, etwa so:

ofstream x("C:\\gabehabe.txt", ios_base::trunc);

  • fopen schneidet den Inhalt der Datei “gabehabe.txt” ab und positioniert den Dateizeiger an den Anfang, richtig? Aber wird es den Inhalt der Datei leeren, bevor der Dateizeiger neu positioniert wird?

    – Arpit

    26. März 2013 um 6:44 Uhr

  • @Arpith: Ja, "w" oder "w+" kürzt die Datei. man7.org/linux/man-pages/man3/fopen.3.html ("w+" öffnet sich für Lesen und Schreiben, sodass Sie schreiben, suchen und lesen können, was Sie geschrieben haben. Für Nur-Schreiben lassen Sie das weg +). Um mit der Fähigkeit zum Schreiben, aber ohne Abschneiden zu öffnen, verwenden Sie "a" oder "a+" (anhängen) bzw "r+".

    – Peter Cordes

    6. April um 7:29


Benutzeravatar von R. Martinho Fernandes
R.Martinho Fernandes

Wenn Sie die gesamte Datei abschneiden möchten, können Sie die Datei zum Schreiben öffnen. Andernfalls müssen Sie die Datei zum Lesen öffnen und die Teile der Datei, die Sie behalten möchten, in eine temporäre Variable einlesen und sie dann an die gewünschte Stelle ausgeben.

Gesamte Datei abschneiden:

FILE *file = fopen("filename.txt", "w"); //automatically clears the entire file for you.

Teil der Datei abschneiden:

FILE *inFile("filename.txt", "r");
//read in the data you want to keep
fclose(inFile);
FILE *outFile("filename.txt", "w");
//output back the data you want to keep into the file, or what you want to output.

  • fopen schneidet den Inhalt der Datei “gabehabe.txt” ab und positioniert den Dateizeiger an den Anfang, richtig? Aber wird es den Inhalt der Datei leeren, bevor der Dateizeiger neu positioniert wird?

    – Arpit

    26. März 2013 um 6:44 Uhr

  • @Arpith: Ja, "w" oder "w+" kürzt die Datei. man7.org/linux/man-pages/man3/fopen.3.html ("w+" öffnet sich für Lesen und Schreiben, sodass Sie schreiben, suchen und lesen können, was Sie geschrieben haben. Für Nur-Schreiben lassen Sie das weg +). Um mit der Fähigkeit zum Schreiben, aber ohne Abschneiden zu öffnen, verwenden Sie "a" oder "a+" (anhängen) bzw "r+".

    – Peter Cordes

    6. April um 7:29


1413680cookie-checkWie schneide ich eine Datei in C ab?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy