Am einfachsten ist es, ein Zeichen zu lesen und direkt nach dem Lesen auszudrucken:
int c;
FILE *file;
file = fopen("test.txt", "r");
if (file) {
while ((c = getc(file)) != EOF)
putchar(c);
fclose(file);
}
c
ist int
oben, da EOF
es sich um eine negative Zahl handelt und eine Ebene sein char
kann unsigned
.
Wenn Sie die Datei in Blöcken lesen möchten, jedoch ohne dynamische Speicherzuweisung, haben Sie folgende Möglichkeiten:
#define CHUNK 1024 /* read 1024 bytes at a time */
char buf[CHUNK];
FILE *file;
size_t nread;
file = fopen("test.txt", "r");
if (file) {
while ((nread = fread(buf, 1, sizeof buf, file)) > 0)
fwrite(buf, 1, nread, stdout);
if (ferror(file)) {
/* deal with error */
}
fclose(file);
}
Die zweite Methode oben ist im Wesentlichen, wie Sie eine Datei mit einem dynamisch zugewiesenen Array lesen:
char *buf = malloc(chunk);
if (buf == NULL) {
/* deal with malloc() failure */
}
/* otherwise do this. Note 'chunk' instead of 'sizeof buf' */
while ((nread = fread(buf, 1, chunk, file)) > 0) {
/* as above */
}
Ihre Methode fscanf()
mit %s
als Format verliert Informationen über Leerzeichen in der Datei, sodass eine Datei nicht genau in diese Datei kopiert wird stdout
.
stdout
.c
int ist und C garantiert, dassEOF
es keinem gültigen Zeichen entspricht.Es gibt hier viele gute Antworten zum Lesen in Stücken. Ich zeige Ihnen nur einen kleinen Trick, der den gesamten Inhalt auf einmal in einen Puffer liest und druckt.
Ich sage nicht, dass es besser ist. Es ist nicht so und wie Ricardo manchmal kann es schlecht sein, aber ich finde es eine gute Lösung für die einfachen Fälle.
Ich habe es mit Kommentaren bestreut, weil viel los ist.
Lass es mich wissen, wenn es nützlich ist oder du etwas daraus lernen könntest :)
quelle
buffer[string_size] = '\0';
statt lesenstring_size+1
? Afaik die eigentliche Saite geht von0
bisstring_size-1
und der\0
Charakter muss also seinstring_size
, oder?ftell
und Ermittelnfseek
der Größe einer Datei ist unsicher: Securecoding.cert.org/confluence/display/seccode/…fclose(handle)
calloc(2)
anstattmalloc(1)
zu überspringen.Drucken Sie die Zeichen stattdessen direkt auf die Konsole, da die Textdatei möglicherweise sehr groß ist und Sie möglicherweise viel Speicher benötigen.
quelle
Verwenden Sie "read ()" anstelle von fscanf:
Hier ist ein Beispiel:
http://cmagical.blogspot.com/2010/01/c-programming-on-unix-implementing-cat.html
Arbeitsteil aus diesem Beispiel:
Ein alternativer Ansatz ist die Verwendung
getc
/putc
zu einer Zeit zum Lesen / Schreiben 1 Zeichen. Viel weniger effizient. Ein gutes Beispiel: http://www.eskimo.com/~scs/cclass/notes/sx13.htmlquelle
read
lässt Sie eine bestimmte Anzahl von Zeichen einlesen. Lesen Sie genug ein, um Ihren Puffer zu füllen, und speichern Sie ihn dann auf dem Bildschirm, löschen Sie ihn und wiederholen Sie den Vorgang, bis Sie das Ende der Datei erreicht haben.Zwei Ansätze fallen mir ein.
Erstens nicht verwenden
scanf
. Verwenden Siefgets()
diesen Parameter, um die Puffergröße anzugeben und alle Zeilenumbrüche intakt zu lassen. Eine einfache Schleife über die Datei, die den Pufferinhalt druckt, sollte die Datei natürlich intakt kopieren.Zweitens verwenden
fread()
oder die gemeinsame C-Sprache mitfgetc()
. Diese würden die Datei in Blöcken fester Größe oder jeweils einem einzelnen Zeichen verarbeiten.Wenn Sie die Datei über durch Leerzeichen getrennte Zeichenfolgen verarbeiten müssen, verwenden Sie entweder
fgets
oderfread
, um die Datei zu lesen, undstrtok
teilen Sie den Puffer in Leerzeichen. Vergessen Sie nicht, den Übergang von einem Puffer zum nächsten zu handhaben, da Ihre Zielzeichenfolgen wahrscheinlich die Puffergrenze überschreiten.Wenn
scanf
für das Lesen eine externe Anforderung erforderlich ist, begrenzen Sie die Länge der Zeichenfolge, die möglicherweise gelesen wird, mit einem Genauigkeitsfeld im Formatbezeichner. Sagen Sie in Ihrem Fall mit einem 999-Byte-Puffer,scanf("%998s", str);
der höchstens 998 Zeichen in den Puffer schreibt, und lassen Platz für den Nullterminator. Wenn einzelne Zeichenfolgen zulässig sind, die länger als Ihr Puffer sind, müssen Sie sie in zwei Teilen verarbeiten. Wenn nicht, haben Sie die Möglichkeit, den Benutzer höflich über einen Fehler zu informieren, ohne eine Sicherheitslücke für den Pufferüberlauf zu erstellen.Überprüfen Sie unabhängig davon immer die Rückgabewerte und überlegen Sie, wie Sie mit fehlerhaften, böswilligen oder nur fehlerhaften Eingaben umgehen sollen.
quelle
Sie können
fgets
die Größe der gelesenen Zeichenfolge verwenden und begrenzen.Sie können das
while
in Ihrem Code ändern in:quelle
Sie könnten die gesamte Datei mit dynamischer Speicherzuordnung lesen, dies ist jedoch keine gute Idee, da bei zu großer Datei Speicherprobleme auftreten können.
Lesen Sie also besser kurze Teile der Datei und drucken Sie sie aus.
quelle