• 22


    由于行长度和文本文件行数均未知,相当于二维 char 数组的两维长度都未定义。由于 getline 函数可以自动扩充 char 数组长度,我最初的想法是使用 getline 得到每行,然后每次对 char ** 进行 realloc,直到读完整个文件。

    但是这种做法并不好,首先 getline 是 glibc 的扩展,而不是 C 语言的标准函数,使用除 gcc 以外的编译器是不一定能编译通过的;其次,每次对 char ** 指针进行 realloc 显得代码很 ugly。可以使用 fgets 替代 getline,但是就要自己来控制一维 char 数组的长度。

    后来想想,换了一种思路,首先将整个文件读入内存,然后根据 '\n' 的个数来计算文件的行数,作为二维数组的长度,然后将所有的 '\n' 替换成 '\0',并将每一行的指针赋给二维 char 数组,代码如下:

    char ** text_2_array(const char *filename)
    {
      char *p, **array;
      int lines;
      if(filename == NULL) return NULL;

      FILE *fp = fopen(filename, "r");
      if(fp == NULL) return NULL;

      /* Get file size. */
      fseek(fp, 0L, SEEK_END);
      long int f_size = ftell(fp);
      fseek(fp, 0L, SEEK_SET);

      /* Allocate space for file content. */
      char *buf = (char *) calloc(f_size, sizeof(char));
      if(buf == NULL) return NULL;

      fread(buf, sizeof(char), f_size, fp);
      fclose(fp);

      /* Get number of lines. */
      for(p=strchr(buf, '\n'), lines=1; p!=NULL; p=strchr(p, '\n'), lines++) {
        if(*p == '\n') p++;
      }

      /* Allocate space for array; split file buffer to lines by change '\n' to
         '\0'. */
      array = (char **) calloc(lines+1sizeof(char*));
      array[0] = buf;
      for(p=strchr(buf, '\n'), lines=1; p!=NULL; p=strchr(p, '\n')) {
        if(*p == '\n') *p++ = '\0';
        if(p != NULL) array[lines++] = p;
      }
      /* Add a terminate NULL pointer. */
      array[lines] = NULL;
      return array;
    }

    其实读文本文件入数组这个功能在很多语言中是很简单的操作,比如 PHP 的 file 函数,或者 Bash 的 (`cat filename`),都可以直接实现这个功能。但是对 C 这种更低级的语言来说,貌似就没那么简单了。我想要了解的是,除了我上面提到的两种思路,有没有更简单或者直接的方法来解决这个问题?比如一些我不熟悉的函数,或者一些 trick。

  • 相关阅读:
    左萧龙(LZ)个人博客
    不同样式的计数
    CSS径向渐变radial-gradient
    优秀的Android资源
    读取csv格式的数据
    php 获取URL 各部分参数
    phpstorm查找替换文件中的变量
    PhpStorm 快捷键大全 PhpStorm 常用快捷键和配置
    phpstorm 代码注释后,撤销某段代码的注释的,快捷键是什么?
    关于thinkphp5手动抛出Http异常时自定义404页面报错的问题
  • 原文地址:https://www.cnblogs.com/dengyigod/p/2577074.html
Copyright © 2020-2023  润新知