Как искать новые строки при чтении из файла в C / C ++ - PullRequest
0 голосов
/ 05 ноября 2011

Я реализую свою собственную версию команды ("cat") в Unix для практики. После этого я заинтересовался реализацией некоторых флагов, таких как (-n) и (-b).

Мой вопрос: Я ищу способ найти пустые и новые строки при чтении из моего файла. Я не могу вспомнить, какую библиотеку или функцию я должен использовать.

Вот исходный код, над которым я работаю:

#include <fcntl.h>
#include <unistd.h>

static int cat_fd(int fd) 
{
   char buf[4096];
   ssize_t nread;

   while ((nread = read(fd, buf, sizeof buf)) > 0) 
   {
      ssize_t ntotalwritten = 0;
      while (ntotalwritten < nread) 
      {
         ssize_t nwritten = write(STDOUT_FILENO, buf + ntotalwritten, nread - ntotalwritten);

         if (nwritten < 1)
         {
            return -1;
         }

         ntotalwritten += nwritten;
      }
   }

   return (nread == 0) ? 0 : -1;
}

static int cat(const char *fname) 
{
   int fd, success;

   if ((fd = open(fname, O_RDONLY)) == -1)
   {
      return -1;
   }

   success = cat_fd(fd);

   if (close(fd) != 0)
   {
      return -1;
   }

   return success;
}


int main(int argc, char **argv) 
{
    int i;

    if (argc == 1) 
    {
       if (cat_fd(STDIN_FILENO) != 0)
          goto error;
    } 

    else 
    {
      for (i = 1; i < argc; i++)
      {
         if (cat(argv[i]) != 0)
         {
            goto error;
         }
      }
    }

    return 0;

    error:
      write(STDOUT_FILENO, "error\n", 6);
      return 1;
}

Любые идеи или предложения, касающиеся моего вопроса, с благодарностью. Я был бы еще более признателен, если бы вы могли напечатать для меня полный прототип функции, который я буду использовать, поскольку я не опытный программист.

Заранее спасибо за вашу помощь.

P.S: Я реализую флаги (-n) и (-b). Таким образом, я с нетерпением жду, чтобы написать номер строки в начале каждой строки в файле, который я читаю.

Ответы [ 2 ]

1 голос
/ 05 ноября 2011

Я помню, что читал, что кошка памяти отображает файлы для быстрого выполнения.Используйте mmap (2).http://kernel.org/doc/man-pages/online/pages/man2/munmap.2.html Я нашел этот пример: http://ladweb.net/src/map-cat.c Я знаю, что это не отвечает на ваш вопрос о новых строках.Я полагаю, что memchr () поможет.

1 голос
/ 05 ноября 2011

Хотя есть функция, которая выполняет линейный ввод файлов в C (она называется fgets), вы не можете использовать ее для cat, потому что:

  • Нет способа узнать максимальную длину линии заранее;
  • Вы потеряете части входных данных, если они содержат нулевые байты.

Вам нужно будет искать символы новой строки в вашем буфере после того, как вы прочитаете его, и, как только вы найдете какие-либо символы, выведите префикс буфера, затем новую строку, номер строки и остаток буфера (с дополнительной обработкой). оставшихся новых строк, конечно).

Более простым решением было бы переключиться на обработку входных данных по одному байту за раз; Вы можете использовать FILE * и fgetc для использования буферизации, предоставляемой CRT, чтобы фактически не выполнять системный вызов для каждого чтения / записи, или читать файл в блоках, как вы делаете сейчас, и выполнять байтовую обработку внутри цикла. Затем нужно написать конечный автомат - если предыдущий символ чтения был символом новой строки, выведите номер строки, если только этот символ не является символом новой строки и не используется опция -b и т. Д.

Это все еще приводит к менее эффективному решению, так что вы можете обрабатывать cat без аргументов специально - то есть переключаться на байтовую обработку, только если вам это нужно. Фактически, это именно то, что делает по крайней мере одна из реальных реализаций cat.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...