6

首先,我通过调用fread将文本读入缓冲区,然后我想逐行读取它,怎么做?我尝试使用 sscanf ,但它似乎不起作用。

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

我知道使用 fgets 是一个好方法。我只想知道天气这种方法可以做同样的事情。

4

4 回答 4

10

尝试这个:

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

对于逐行阅读,您可以使用:fgets(line, 128, fp)getline(&line, &size, fp);

编辑

如果要从变量中读取它,请查看strtok()函数:

char * line = strtok(strdup(buffer), "\n");
while(line) {
   printf("%s", line);
   line  = strtok(NULL, "\n");
}
于 2012-05-12T02:22:53.820 回答
8

您可以使用strchr()找到行尾字符的位置,如下所示:

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

之前的一切*eol都是第一行。line然后从to前进eol + 1,删除任何后续的\ror\n字符,并重复该过程,直到strchr()返回NULL表明没有更多的换行符。此时,将所有剩余数据移动到缓冲区的开头并从文件中读取下一个块。

如果您担心效率,您可以通过使用 2 个缓冲区并在它们之间交替来避免移动数据,但即使是简单的方法也可能比fgets()文件有很多行更快。

于 2012-05-12T02:30:25.337 回答
2

strtok怎么样

char *line;
line = strtok(texbuf, '\n');
于 2012-05-12T02:23:26.373 回答
0

您说“我知道使用 fgets 是一种好方法。我只是想知道这个方法是否可以做同样的事情。”当然可以,您只需像在 c 库中那样重新实现 fgets 即可。c 库实际上并没有逐行读取,它读取整个块并在您调用 fgets 时给您一行。

这不是一种有效的方法,而是您必须做的事情的样本。

#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);
}
于 2012-05-12T02:29:37.877 回答