Was ist der einfachste Weg (am wenigsten fehleranfällig, am wenigsten Codezeilen, wie auch immer Sie sie interpretieren möchten), um eine Datei in C zu öffnen und ihren Inhalt in eine Zeichenfolge einzulesen (char *, char [], was auch immer)?
96
string s = File.ReadAllText(filename);
. Wie könnte das einfacher und fehleranfälliger sein?Antworten:
Ich neige dazu, einfach den gesamten Puffer als Rohspeicherblock in den Speicher zu laden und das Parsen selbst durchzuführen. Auf diese Weise habe ich die beste Kontrolle darüber, was die Standardbibliothek auf mehreren Plattformen tut.
Dies ist ein Stummel, den ich dafür benutze. Möglicherweise möchten Sie auch die Fehlercodes für fseek, ftell und fread überprüfen. (aus Gründen der Übersichtlichkeit weggelassen).
quelle
fread
Ihre Zeichenfolge nicht mit Null abgeschlossen wird. Dies kann zu Problemen führen.buffer = malloc (length + 1);
nach fclose ändern und hinzufügen:buffer[length] = '\0';
(validiert von Valgrind)Eine andere, leider stark vom Betriebssystem abhängige Lösung ist die Speicherzuordnung der Datei. Zu den Vorteilen gehören im Allgemeinen die Leseleistung und die geringere Speichernutzung, da die Anwendungsansicht und der Dateicache des Betriebssystems den physischen Speicher tatsächlich gemeinsam nutzen können.
POSIX-Code würde folgendermaßen aussehen:
Windows hingegen ist etwas kniffliger, und leider habe ich keinen Compiler zum Testen vor mir, aber die Funktionalität wird von
CreateFileMapping()
und bereitgestelltMapViewOfFile()
.quelle
Wenn "Inhalt in eine Zeichenfolge einlesen" bedeutet, dass die Datei keine Zeichen mit dem Code 0 enthält, können Sie auch die Funktion getdelim () verwenden, die entweder einen Speicherblock akzeptiert und ihn bei Bedarf neu zuweist oder nur den gesamten Puffer für zuweist Sie und liest die Datei hinein, bis sie auf ein bestimmtes Trennzeichen oder Dateiende stößt. Übergeben Sie einfach '\ 0' als Trennzeichen, um die gesamte Datei zu lesen.
Diese Funktion ist in der GNU C-Bibliothek unter http://www.gnu.org/software/libc/manual/html_mono/libc.html#index-getdelim-994 verfügbar
Der Beispielcode sieht möglicherweise so einfach aus wie
quelle
Wenn es sich bei der Datei um Text handelt und Sie den Text zeilenweise abrufen möchten, verwenden Sie am einfachsten fgets ().
quelle
Wenn Sie spezielle Dateien wie stdin oder eine Pipe lesen, können Sie fstat nicht verwenden, um die Dateigröße im Voraus zu ermitteln. Wenn Sie eine Binärdatei lesen, verlieren fgets aufgrund der eingebetteten '\ 0'-Zeichen die Informationen zur Zeichenfolgengröße. Der beste Weg, eine Datei zu lesen, ist die Verwendung von read und realloc:
quelle
Hinweis: Dies ist eine Änderung der oben akzeptierten Antwort.
Hier ist eine Möglichkeit, dies zu tun, einschließlich der Fehlerprüfung.
Ich habe eine Größenprüfung hinzugefügt, um zu beenden, wenn die Datei größer als 1 GiB war. Ich habe dies getan, weil das Programm die gesamte Datei in eine Zeichenfolge einfügt, die möglicherweise zu viel RAM verwendet und einen Computer zum Absturz bringt. Wenn Sie sich jedoch nicht darum kümmern, können Sie es einfach aus dem Code entfernen.
Und um nach Fehlern zu suchen:
quelle
Wenn Sie verwenden
glib
, können Sie g_file_get_contents verwenden .quelle
Dies ist eine ziemlich grobe Lösung, da nichts gegen Null geprüft wird.
quelle
glShaderSource
optional benötigt wird.Nur geändert von der oben akzeptierten Antwort.
quelle
Ich werde meine eigene Version hinzufügen, basierend auf den Antworten hier, nur als Referenz. Mein Code berücksichtigt sizeof (char) und fügt einige Kommentare hinzu.
quelle
einfach und ordentlich (vorausgesetzt, der Inhalt der Datei beträgt weniger als 10000):
quelle