2012-05-12 6 views
5

Zuerst lese ich einen Text in einen Puffer durch den Aufruf von fread, und dann möchte ich es Zeile für Zeile lesen, wie es geht? Ich versuche ein sscanf zu verwenden, aber es scheint nicht zu funktionieren.Wie kann ich zeilenweise lesen, nachdem ich einen Text in einen Puffer gelesen habe?

char textbuf[4096]; 
char line[256]; 
FILE *fp; 
fp = fopen(argv[1],"r"); 
memset(textbuf, 0, 4096); 
fread(textbuf, 1, 4096, fp); 

Ich weiß, mit Fgets ist ein guter Weg. Ich möchte nur wissen, dass diese Methode das gleiche tun kann.

+0

Warum verwenden Sie 'fgets()', um die Datei Zeile für Zeile zu lesen? –

+0

Oder 'getline()', wenn Sie auf System POSIX-kompatibel sind. – Jack

Antwort

7

Try this:

fgets(textbuf, sizeof(textbuf), fp); 

Für lesenden Zeile für Zeile können Sie: fgets(line, 128, fp) oder getline(&line, &size, fp);

EDIT

Wenn Sie es von einer Variablen lesen möchten, schauen Sie sich strtok() Funktion:

char * line = strtok(strdup(buffer), "\n"); 
while(line) { 
    printf("%s", line); 
    line = strtok(NULL, "\n"); 
} 
+0

'fgets()' oder 'getline()'? Entscheide dich! :-) –

+0

@AdamLiss: Es kommt drauf an. Sehen Sie, dass Sie hier zwei Fragen haben. Einer kann nur mit fgets() gelöst werden und ein anderer kann mit fgets() oder getline() gelöst werden. – Jack

+0

beide fgets und getline brauchen Datei Poiter, also, es gibt keine Notwendigkeit, fread aufzurufen. Ich möchte Zeile für Zeile aus dem Puffer lesen, wie? –

2

wie etwa strtok

char *line; 
line = strtok(texbuf, '\n'); 
+0

Seien Sie vorsichtig mit 'strtok()'. Es ist nicht wiedereintrittsfähig, und es ändert seine Eingabe, während es es verarbeitet. –

+0

@nos yeah, das habe ich schon gewusst, also ist es nur ein Versuch. eine alternative Methode. Ich denke, 'fgets' ist das einfachste. –

0

Sie sagte: „Ich weiß fgets ist eine gute Art und Weise. Ich will nur wissen, ob diese Methode das gleiche kann. "Natürlich können Sie fgets wie in der c-Bibliothek implementieren. Die c-Bibliothek liest nicht Zeile für Zeile, sondern liest ein Ganzes ein Brocken und gibt Ihnen eine Linie, wenn Sie fgets nennen.

keine effiziente Art und Weise, sondern eine Probe von der Art der Dinge, die Sie tun müssen.

#include <stdio.h> 
typedef struct my_state { 
unsigned char * buf; 
int offset; 
int buf_size; 
int left; 
FILE * file; 
} my_state_t; 
int takeone(my_state_t * state) { 
if ((state->left - state->offset)<=0) { 
    if (feof(state->file)) return -1; 
    state->left = fread(state->buf,1,state->buf_size,state->file); 
    state->offset = 0; 
    if (state->left == 0) return -1; 
} 
return state->buf[state->offset++]; 
} 
int getaline(my_state_t * state, char * out, int size) { 
int c; 
c = takeone(state); 
if (c < 0) return 0; 
while (c >=0 && size > 1) { 
    *out++ = c; 
    --size; 
    if (c == '\n') break; 
    c = takeone(state); 
} 
*out=0; 
return 1; 
} 
int main(int argc, char ** argv){ 
FILE *fp; 
char textbuf[4096]; 
char line[256]; 
my_state_t fs; 
fs.buf=textbuf; 
fs.offset=0; 
fs.buf_size=4096; 
fs.left=0; 
fp = (argc>1)? fopen(argv[1],"rb") : stdin; 
fs.file = fp; 
while (getaline(&fs,line,256)) { 
    printf("-> %s", line); 
} 
fclose(fp); 
} 
+0

das ist fast was ich will. Ich vergesse fast, dass 'fgets' eine Bibliotheksfunktion ist, kein Systemanruf. –

5

Sie können die Position des End-of finden -Linie Charakter strchr() wie folgt aus:

char *eol = strchr(line, '\n'); 

Alles vor *eol ist die erste Zeile. Wechseln Sie dann von line zu eol + 1, entfernen Sie alle nachfolgenden Zeichen \r oder \n, und wiederholen Sie den Vorgang, bis strchr()NULL zurückgibt, um anzuzeigen, dass keine weiteren Zeilenumbruchzeichen vorhanden sind. Verschieben Sie an diesem Punkt alle verbleibenden Daten an den Anfang des Puffers und lesen Sie den nächsten Chunk aus der Datei.

Wenn Sie über die Effizienz besorgt sind, können Sie vermeiden, die Daten mit 2 Puffern zu verschieben und zwischen ihnen zu wechseln, aber selbst die naive Methode ist wahrscheinlich schneller als fgets(), wenn die Datei viele Zeilen hat.

+0

Ja, ich denke, das funktioniert. –

+0

Beste und einfachste Version bisher! – br1

Verwandte Themen