c - 如何编写一个函数,从文件描述符中读取并返回一行而不用 C 中的 '\n'

标签 c

我只被允许使用malloc、read和free。 我还可以使用 string.h 中的函数

该程序应使用以下方式编译:

gcc -Wall -Wextra -Werror -D BUFFER_SIZE=32 get_next_line.c

包括:

#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <fcntl.h>
#define BUFFER_SIZE 32

该函数的原型(prototype)应为:

int get_next_line(int fd, char **line);

最佳答案

也许我会做这样的事情:

  #include <string.h>       // strlen()
  #include <unistd.h>       // read(), write(), close()
  #include <stdlib.h>       // EXIT_SUCCESS, realloc(), free()
  #include <fcntl.h>        // O_RDONLY

  #define EOF (-1)          // Flag to indicate that the end-of-file was encountered.
  extern int errno;         // Used to detect, and report, error information.

  /*----------------------------------------------------------------------------
  ** Read a line from specified file (fd), and return the line in allocated
  ** memory.  The caller is responsible for freeing the returned memory.
  **
  ** Return codes:
  ** -------------
  ** -1 EOF           Encountered the end of the file (fd).
  **  0 EXIT_SUCCESS  Success.
  ** >1 (errno value) Failure.
  */
  int get_next_line(int fd, char **line)
    {
    int    rCode      = EXIT_SUCCESS;
    size_t lineOffset = 0;

    while(!rCode)
      {
      char *newBuf = NULL;
      int   bytes;
      char  ch;

      bytes=read(fd, &ch, sizeof(ch));         // Read one byte from file (fd).
      switch(bytes)
        {
        case (-1):                             // Check for read() error condition.
          rCode=errno;                           // Return errno to caller.
          break;                                 // Return from the function.

        case 0:                                // Check for end-of-file condition.
          rCode = EOF;                           // Return EOF flag to caller.
          ch = '\0';                             // Pretend to have read '\0'.
                                                 // No break.  Fall through to default case.
        default:                               // read() was successful.
          newBuf=realloc(*line, lineOffset+2);   // Modify line's memory allocation as needed.
          if(!newBuf)                            // Check for realloc() error condition.
            {
            rCode=errno;                           // Return errno to caller.
            break;                                 // Return from the function.
            }

          *line = newBuf;                        // realloc() was successful.  Reset line pointer.
          if('\n' == ch)                         // If newline was read, throw it away
            {
            (*line)[lineOffset] = '\0';            // Instead of a newline, terminate the line,
            break;                                 // and return from the function.
            }

          (*line)[lineOffset++] = ch;            // Append the character read from the file to the allocated memory.
          (*line)[lineOffset] = '\0';            // Terminate the string in allocated memory.
          continue;                              // Go back to the top of the while() loop, and read another byte.
        }

      break;
      }

    return(rCode);
    }

  /*----------------------------------------------------------------------------
  ** Program start.
  */
  int main(int argC, char *argV[])
    {
    int rCode=EXIT_SUCCESS;
    int fd = (-1);
    char *line_A = NULL;

    if(2 != argC)
      {
      char *msg = "Missing filename, or too many command-line arguments.\n";

      write(2, msg, strlen(msg));
      goto CLEANUP;
      }

    errno=EXIT_SUCCESS;
    fd=open(argV[1], O_RDONLY);
    if((-1) == fd)
      {
      char *msg = "open() failed.\n";

      write(2, msg, strlen(msg));
      goto CLEANUP;
      }

    while(EOF != rCode)
      {
      rCode=get_next_line(fd, &line_A);
      if(rCode > 0)
        goto CLEANUP;

      write(1, line_A, strlen(line_A));
      write(1, "\n", 2);
      }

  CLEANUP:

    if(line_A)
      free(line_A);

    if((-1) != fd)
      close(fd);

    return(rCode);
    }

关于c - 如何编写一个函数,从文件描述符中读取并返回一行而不用 C 中的 '\n',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58572353/

相关文章:

c - 棋盘游戏程序中的数组

c - C 中的 For 循环打印出各个整数。

c++ - 在类似于 unix shell 脚本的 c++ 中调用后台函数

c - 如何使用 void 函数创建链表?

c++ - 在C中如何在命令行中定义所有未知宏(在源文件/头文件中使用)

java - 使用 native 语言为 C 或 C++ 的 JNI 接口(interface)在 Java 中实现 USB 通信是个好主意吗?

c - 为什么可以将 sa_family,一个无符号整数,一个由 socket.h 定义的结构体与 AF_INET 进行比较

c -++i 和 i++ 有什么区别?

c - C 中的循环展开

我可以以头文件实现中不存在的方式使用结构吗?