Wie zu Lesen Eingabe unbekannter Länge mit fgets
Wie soll ich Lesen, lange Eingabe mit fgets()
ich nicht ganz kapiert.
Schrieb ich diese
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char buffer[10];
char *input;
while (fgets(buffer,10,stdin)){
input = malloc(strlen(buffer)*sizeof(char));
strcpy(input,buffer);
}
printf("%s [%d]",input, (int)strlen(input));
free(input);
return 0;
}
Blick auf
Wenn Sie es haben, sollten Sie mithilfe von
ich weiß, über getline, aber ich habe die Verwendung der Funktion fgets
ich sah Sie, aber ich dont verstehen, von der es, wie fgets funktioniert, was passiert, wenn die Eingabe länger ist, dann buffer ich angeben, macht es für mich warten, um Speicher zuzuweisen und speichern Sie es?
Dein code hat ein klassischer off-by-one Fehler in der
realloc
. Und überlegen Sie eine Strategie der Verdopplung der Zuweisung jeder Zeit, wie auch die Lektüre direkt in den Puffer. BTW: Die printf-format für size_t
ist %zu
.Wenn Sie es haben, sollten Sie mithilfe von
getline
statt fgets
.ich weiß, über getline, aber ich habe die Verwendung der Funktion fgets
ich sah Sie, aber ich dont verstehen, von der es, wie fgets funktioniert, was passiert, wenn die Eingabe länger ist, dann buffer ich angeben, macht es für mich warten, um Speicher zuzuweisen und speichern Sie es?
Dein code hat ein klassischer off-by-one Fehler in der
malloc()
. Mit strlen(str)
ist fast immer falsch; Sie sollte fast immer strlen(str)+1
. Ihre Schleife Speicherverluste schrecklich, zu; Sie überschreiben den vorherigen Zeiger gespeichert in input
bei jeder iteration.InformationsquelleAutor lllook | 2014-12-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies ist über die minimale Anzahl der änderungen, geben Sie die vollständige Zeile der Eingabe. Dieser wächst der Speicherplatz um bis zu 9 bytes auf ein mal; das ist nicht der beste Weg, es zu tun, aber es gibt extra Buchhaltung beteiligt sind, tun es die besseren Möglichkeiten (Verdoppelung der Speicherplatz, und halten Sie eine Aufzeichnung von, wie viel reserviert ist vs wie viel verwendet wird). Beachten Sie, dass
cur_len
aufzeichnen die Länge der Zeichenfolge in den Raum, wies auf die voninput
ohne das terminal null. Beachten Sie auch, dass die Verwendung vonextra
vermeidet ein Speicherverlust auf Fehler bei der Zuordnung.Den
strcpy()
Betrieb könnte legitimerweise ersetzt durchmemmove(input + cur_len, buffer, buf_len + 1)
(und in diesem Zusammenhang könnten Siememcpy()
stattmemmove()
, aber es funktioniert nicht immer, währendmemmove()
bedeutet immer Arbeit, so ist es mehr zuverlässig zu bedienenmemmove()
).Länge-Verdoppelung, — die
cur_max
variable Datensätze, wie viel Speicherplatz reserviert, und diecur_len
zeichnet auf, wie viel Speicherplatz verwendet wird.Nein; das einfachste ist die Verwendung
char buffer[4096];
und mit dem Leben. Nur JSON kommt in Zeilen, die länger als das, und dann bekommt man zu Lesen die gesamte Datei in eine Zeile. (Ich übertreibe, aber nicht so viel, wie alle das.) Gelingt das nicht, die Idee ist, dass Sie zuweisen von 10 bytes der ersten Zeit, dann reservieren 20, dann Neuverteilung der 40 (aber Lesen Sie 2 Einheiten von 10 in den extra-Raum), dann 80, dann 160 dann 320... Wenn du nicht gehst, um kostenlos den Speicherplatz, bevor die Funktion beendet und es gibt mehr als, sagen wir, 64 Byte unbenutzt, Sie könnte verwendenrealloc()
zu verkleinern die Zuordnung auf die gewünschte Größe.Es sei denn, du bist auf einen winzig kleinen Maschine, einer 4 Kb-Puffer ist nicht zu führen, dass Sie Trauer. Wenn Sie auf solch eine winzige Maschine, die Sie wahrscheinlich nicht verwenden
malloc()
an - oder Lesen-so lange Zeilen.danke für die Antwort, was bedeutet, wenn (extra == 0) break; tut dies zu Ihrer änderung, ist 0 representiing 'NULL'?
NULL ist ein anderer name für 0 - mehr oder weniger. Es gibt Komplikationen, aber beide sind (oder werden kann) null-Zeiger-Konstanten. Sie können 0 in Orten, die Sie sollten nicht NULL; es gibt nirgendwo können Sie NULL, dass Sie nicht verwenden können, 0. In C, einige Systeme definieren, die NULL als
((void *)0)
oder so ungefähr; das nicht-Fliegen-in C++ (aber den richtigen Wert für die NULL ist ein problem für den compiler, nicht der Programmierer mit NULL). Mit NULL können Sie, wo ich schrieb 0:char *input = NULL;
,while (fgets(buffer, sizeof(buffer), stdin) != NULL)
,if (extra == NULL)
.InformationsquelleAutor Jonathan Leffler
Ein besserer Ansatz ist die Verwendung einer input-Mechanismus, die Zuordnung, für Sie wie
getline
(oder sogarscanf
). (Hinweis:scanf
reserviert nicht in allen Compilern. Ingcc/Linux
, aber nicht mitWindows/Codeblocks/gcc
)Ausgabe:
getline Beispiel
Wenn Sie unter Windows arbeiten,
scanf
wird nicht reserviert, wenn mitcodeblocks
usw.., Verwendunggetline
. Ich werde das update für Linux nur. Ich arbeitete mitgcc/C89
mit gnu-Erweiterungen.ich bin kompilieren auf linux, in codeblocks
Loswerden von codeblocks
:)
ich habe andere berichten, dassscanf
wird nicht reserviert, wenn mitcodeblocks
. Es muss eine Einschränkung sein.Code::Blocks hat nichts zu tun mit dem kompilieren. Es ist nur die IDE
InformationsquelleAutor David C. Rankin