Lesen einer Textdatei in ein Array in c

Lesezeit: 3 Minuten

Benutzer-Avatar
verringern

Was wäre die effizienteste Methode zum Einlesen einer Textdatei in ein dynamisches eindimensionales Array? Neuzuweisung nach jedem gelesenen Zeichen scheint albern, Neuzuweisung nach jeder gelesenen Zeile scheint nicht viel besser zu sein. Ich möchte die gesamte Datei in das Array einlesen. Wie würdest du es machen?

  • Ich habe möglicherweise missverstanden, was Sie tun möchten: Möchten Sie nur die gesamte Datei in einen großen Puffer einlesen, oder möchten Sie ein Array mit einem Eintrag für jede Zeile?

    – Christoph

    4. Januar 2009 um 17:05 Uhr

Benutzer-Avatar
Johannes Schaub – litb

Ich verstehe nicht ganz was du willst. Möchten Sie die Datei inkrementell verarbeiten, eine Zeile daraus lesen, sie dann verwerfen und die nächste verarbeiten? Oder möchten Sie die gesamte Datei in einen Puffer einlesen? Wenn Sie letzteres möchten, ist dies meiner Meinung nach angemessen (prüfen Sie auf NULL-Rückgabe für malloc und fopen in echtem Code, ob die Datei vorhanden ist und ob Sie genügend Speicher haben):

FILE *f = fopen("text.txt", "rb");
fseek(f, 0, SEEK_END);
long pos = ftell(f);
fseek(f, 0, SEEK_SET);

char *bytes = malloc(pos);
fread(bytes, pos, 1, f);
fclose(f);

hexdump(bytes); // do some stuff with it
free(bytes); // free allocated memory

  • Ja, das würde auf meinen Fall zutreffen. Ich meinte, dass die Verwendung von realloc nach jedem Lesezeichen sehr ineffizient erscheint, ähnlich nach jedem Lesevorgang \n (um das Array zu erweitern).

    – verringern

    4. Januar 2009 um 13:15 Uhr

  • Sie sollten die Datei im Binärmodus öffnen – sonst könnte es Probleme geben (siehe zB glibc-Handbuch, 12.17)

    – Christoph

    4. Januar 2009 um 13:40 Uhr

  • Hallo, was ist der Unterschied zwischen (angenommen, wir verwenden 100 anstelle von pos) char *bytes = malloc(100*sizeof(char)); und über der Zeile, wo Sie geschrieben haben char *bytes = malloc(100); Die zweite Frage ist, was passiert, wenn meine Datei 180205962 Zeichen enthält. Wird die obige Art, die Datei zu lesen, effizient sein?

    – assel

    30. Dezember 2009 um 20:56 Uhr


  • @asel, erste Frage: sizeof(char) ist als 1 definiert, also gibt es keinen Unterschied. Zweite Frage: Nein, Sie sollten es wahrscheinlich schrittweise lesen (z. B. Zeile für Zeile oder eine andere stückweise Methode). Sonst ist Ihr Gedächtnis schnell erschöpft.

    – Johannes Schaub – litb

    30. Dezember 2009 um 21:37 Uhr

  • Die Verwendung von fseek/ftell zum Abrufen der Dateigröße ist unsicher. Warum das so ist und wie man es sicher macht, erfahren Sie in dieser CERT-Referenz: securecoding.cert.org/confluence/display/seccode/…

    – Bryan

    9. Dezember 2012 um 23:31 Uhr

Benutzer-Avatar
Philant

Wenn Karte(2) auf Ihrem System verfügbar ist, können Sie die Datei öffnen und dem Speicher zuordnen. Auf diese Weise müssen Sie keinen Speicher zuweisen, Sie müssen die Datei nicht einmal lesen, das System erledigt dies. Sie können den fseek()-Trick verwenden, den litb gegeben hat, um die Größe zu erhalten.

void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);

BEARBEITEN: Sie müssen verwenden lseek() um die Größe der Datei zu erhalten, .

int fd = open("filename", O_RDONLY);
int nbytes = lseek(fd, 0, SEEK_END);
void *content = mmap(NULL, nbytes, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);

  • @saffsd Sie haben genug Repräsentanten, um das Problem zu beheben. Sie wissen, wie es hier funktioniert.

    – Philant

    5. September 2014 um 6:33 Uhr

  • vergessen, Kommentar korrigiert und gelöscht.

    – saffsd

    6. September 2014 um 8:34 Uhr


  • Ein möglicherweise idiomatischerer Weg, um die Dateigröße zu erhalten, ist zu verwenden fstat(2) Funktion: struct stat S; fstat(fd, &S);dann int nbytes = S.st_size ist die Dateigröße in Bytes, direkt aus dem Dateisystem, ohne dass die Datei gelesen wird (dies würde zweifellos das gleiche Ergebnis wie oben ergeben; ich erwähne es größtenteils der Vollständigkeit halber).

    – Norman Grau

    28. Oktober 2015 um 22:13 Uhr

Benutzer-Avatar
Christoph

Wenn Sie ISO C verwenden möchten, verwenden Sie diese Funktion.

Es ist die Antwort von litb, verpackt mit etwas Fehlerbehandlung …

1178790cookie-checkLesen einer Textdatei in ein Array in c

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

Privacy policy