【问题标题】:recoding getline function on C在 C 上重新编码 getline 函数
【发布时间】:2013-07-19 10:10:02
【问题描述】:

我需要一个函数来为另一个程序重现基本的 getline 函数,这个函数应该能够正确读取 FP 并且没有巨大的缓冲区(这里 256 应该足够了) 我对下面的代码有 2 个问题 - 当缓冲区被执行时,函数开始返回错误信息,例如 http://pastebin.com/BXj3SH92 ( ./a.out

代码如下:

#define MOAR_BUF 256

#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>

char            *my_getline(const int fd)
{
  static char   save[MOAR_BUF];
  static int    i = MOAR_BUF;
  int           g;
  int           f;
  char          *save2;

  save2 = NULL;
  g = 0;
  f = 0;
  if (g == 0 && i >= (MOAR_BUF -1))
    {
      i = 0;
      g = read(fd, save, MOAR_BUF + 1);
      save[g] = '\0';
    }
  if (i <= MOAR_BUF && save[i] != '\0')
    {
      save2 = malloc((sizeof(*save2) * MOAR_BUF));
      while(save[i] != '\n' && save[i] != '\0')
        save2[f++] = save[i++];
      save2[f] = '\0';
      if (save[i] != '\0')
        i = i + 1;
    }
  return(save2);
}

int             main()
{
  int           i;
  char          **converted_map;
  char          *map;

  i = 0;
  converted_map = malloc(sizeof(*converted_map) * 30);
  while(map = my_getline(0))
    {
      converted_map[i] = strdup(map);
      printf("%s\n", converted_map[i]);
      i++;
    }
}

【问题讨论】:

  • 您的malloc() 并不完全正确:您将MOAR_BUFsizeof(save2) 相乘,得到sizeof(char *)。但这只会使缓冲区太大,不会引起任何问题
  • 已修复,我意识到我不必 malloc **converted_map 顺便说一句我不知道为什么

标签: c getline


【解决方案1】:
static char   save[MOAR_BUF];

g = read(fd, save, MOAR_BUF);
save[g] = '\0';

您告诉read 读取MOAR_BUF 字节,当它成功读取那么多字节时,0 终止符会写入数组末尾,调用未定义的行为。

您需要告诉read 读取更少的字节,例如MOAR_BUF - 1,或者使缓冲区更大,例如MOAR_BUF + 1

那么,在main

while(map = my_getline(0))
{
  printf("%s\n", converted_map[i]);
  converted_map[i] = strdup(map);
  i++;
}

您在分配之前打印出converted_map[i],这是更多未定义的行为。你需要strdup(map)converted_map[i]然后你就可以打印了。

【讨论】:

  • 它适用于小文件,但当 MOAR_BUF 超过其值时,我开始返回错误
  • if (i &lt;= MOAR_BUF &amp;&amp; save[i] != '\0') 更多越界访问。修复越界错误,如果之后仍然无法正常工作,请举例说明问题所在。除此之外,您会泄漏内存,您永远不会 free 任何您的 malloced 指针,但这可能只是这里的代码。
  • @Saxtheowl 除了越界访问之外,您在分配converted_map[i] 之前尝试打印它似乎是一个麻烦的原因。
  • 我不明白您所说的越界访问是什么意思,对于错误示例,当我输入 ./a.out pastebin.com/9vhxzPYG) 我明白了:pastebin.com/5ZN7qx9R
  • @Saxtheowl 您正在访问save[256]。但最后一个有效索引是255。您是否抱怨某些线路被分割了?那是因为您从不检查 save 内容是否以换行符结尾,所以只要行长度加起来不等于缓冲区长度的倍数,就会拆分。我认为这是故意的,因为您根本没有用于连接分割线的代码。
猜你喜欢
  • 1970-01-01
  • 2010-11-10
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
  • 1970-01-01
  • 2021-07-09
  • 2013-11-30
  • 2012-09-21
相关资源
最近更新 更多