如何在C/C+中读取文件时搜索新行+;

如何在C/C+中读取文件时搜索新行+;,c,unix,file-io,C,Unix,File Io,我正在Unix中实现自己版本的(“cat”)命令以供练习。之后,我开始对实现一些标志感兴趣,比如(-n)和(-b) 强>我的问题:我正在寻找一种方法来从我的文件中读取空白和新行。我不记得应该使用什么库或函数 以下是我正在编写的源代码: #include <fcntl.h> #include <unistd.h> static int cat_fd(int fd) { char buf[4096]; ssize_t nread; while ((nr

我正在Unix中实现自己版本的(“cat”)命令以供练习。之后,我开始对实现一些标志感兴趣,比如(-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;
}
#包括
#包括
静态内部cat_fd(内部fd)
{
char-buf[4096];
ssize_t nread;
而((nread=read(fd,buf,sizeof buf))>0)
{
ssize_t ntotalwrited=0;
while(nTotalWrite
非常感谢您对我的问题提出任何意见或建议。 如果您能为我键入完整的函数原型,我将使用,因为我不是一个经验丰富的程序员,我将更加感激

提前感谢你的帮助


我正在实现(-n)和(-b)标志。因此,我希望在我正在读取的文件中的每一行的开头写上行号。

虽然有一个函数可以在C中进行基于行的文件输入(它被称为
fgets
),但实际上不能将它用于cat,因为:

  • 事先无法知道线路的最大长度
  • 如果输入包含空字节,则会丢失部分输入
在读取缓冲区后,您必须在缓冲区中查找换行符,一旦找到,请打印缓冲区的前缀,后跟换行符、行号和缓冲区的其余部分(当然,还需要对剩余的换行符进行额外处理)

一个更简单的解决方案是切换到一次处理一个字节的输入;您可以使用FILE*和fgetc来使用CRT提供的缓冲,这样您就不会像现在这样对每次读/写进行系统调用,或者以块的形式读取文件,而是在循环中进行字节处理。然后就是写一个状态机的问题——如果先前读取的字符是换行符,那么输出一个行号,除非这个字符是换行符并且使用了-b选项,等等


这仍然会导致效率较低的解决方案,因此您可能希望在不使用参数的情况下特别处理cat,即仅在需要时切换到逐字节处理。事实上,这正是至少一个实际的cat实现所做的。

我记得读过cat内存映射文件以实现快速执行。使用mmap(2)。 我发现这个例子: 我知道这不能回答你关于新线的问题。我猜
MimCh()将执行这个技巧。

在猫的时候,你不需要定位空白和换行。我正在实现(-n)和(-b)标志。我需要在文件中的每一行都提示行号。为什么C++标签?我只看到C代码,这是因为C++程序员知道如何读取C代码。使用MimCHR是一种有效的方法来搜索缓冲区中的特定字符。谢谢您的精确答案!我真的很感激:)我按照你告诉我的方式做了,现在它工作得很好。理论上,mmap()比较慢。它需要另外两次系统调用,分配和设置分页表条目也不是免费的。从程序员的角度来看,它可能更优雅。