Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Как читать построчно после того, как я прочитал текст в буфер?

Автор вопроса: Fei XueОтветов: 4

Сначала я читаю текст в буфер, вызывая 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 - хороший способ. Я просто хочу знать, может ли этот метод сделать то же самое.

  • Почему бы не использовать fgets() для чтения файла по одной строке за раз? Adam Liss 12.05.2012
  • Или getline(), если вы используете систему, совместимую с POSIX. Jack 12.05.2012

cfread

Ответы

Ответ 1 · рейтинг 9 · Jack

Попробуй это:

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");
}

Ответ 2 · рейтинг 8 · Adam Liss

Вы можете найти расположение символа конца строки, используя strchr() следующим образом :

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

Все, что до *eol, является первой строкой. Затем перейдите от line к eol + 1, удалите все последующие символы \r или \n и повторяйте процесс, пока strchr() не вернет NULL, чтобы указать, что больше нет символов новой строки. В этот момент переместите все оставшиеся данные в начало буфера и прочитайте следующий фрагмент из файла.

Если вы беспокоитесь об эффективности, вы можете избежать перемещения данных, используя 2 буфера и чередуя их, но даже наивный метод, вероятно, быстрее, чем fgets(), если в файле много строк.

Ответ 3 · рейтинг 2 · Musa

как насчет strtok

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

Ответ 4 · pizza

Вы сказали: "Я знаю, что использование fgets - хороший способ. Я просто хочу знать, может ли этот метод делать то же самое". Конечно, вы можете, вы просто повторно реализуете fgets, как в библиотеке c. Библиотека 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);
}

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы