可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
First , I read a text into a buffer by calling fread, and then I want to read it line by line, how to do it? I try to use a sscanf , but it seems not to work.
char textbuf[4096]; char line[256]; FILE *fp; fp = fopen(argv[1],"r"); memset(textbuf, 0, 4096); fread(textbuf, 1, 4096, fp);
I know using fgets is a good way. I just want to know weather this method can do the same thing.
回答1:
Try this:
fgets(textbuf, sizeof(textbuf), fp);
For read line by line you can use: fgets(line, 128, fp)
or getline(&line, &size, fp);
EDIT
If you want to read it from a variable, look at strtok()
function:
char * line = strtok(strdup(buffer), "\n"); while(line) { printf("%s", line); line = strtok(NULL, "\n"); }
回答2:
You can find the location of the end-of-line character using strchr() like this:
char *eol = strchr(line, '\n');
Everything before *eol
is the first line. Then advance from line
to eol + 1
, remove any subsequent \r
or \n
characters, and repeat the process until strchr()
returns NULL
to indicate there are no more newline characters. At that point, move any remaining data to the beginning of the buffer and read the next chunk from the file.
If you're concerned about efficiency you can avoid moving the data by using 2 buffers and alternating between them, but even the naive method is probably faster than fgets()
if the file has many lines.
回答3:
how about strtok
char *line; line = strtok(texbuf, '\n');
回答4:
You said "I know using fgets is a good way. I just want to know weather this method can do the same thing.", of course you can, you just re-implement fgets as in the c library. The c library doesn't actually read line by line, it reads in a whole chunk and gives you a line when you call fgets.
Not an efficient way, but a sample of the kind of things you have to do.
#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); }