【问题标题】:Length of line in getline() function - cgetline() 函数中的行长 - c
【发布时间】:2013-11-30 21:53:05
【问题描述】:

我有一个关于函数 getline() 的问题:

getline(&line, &len, file_in);

file_in 在哪里:

文件 *file_in;

char *line = NULL;

size_t len;

每次我读取任何一行时,分配的内存(len 变量)都是120

我认为它是恒定的,因为它是文件中的默认行大小。

1) 但是为什么是120

2) 这个默认大小可以在任何地方更改吗?

3) 是否有任何只计算写入字符的 C 函数?

【问题讨论】:

  • 试试 "printf("line length is %d\n", strlen(line));"

标签: c


【解决方案1】:
  1. 使用 120 作为初始分配是编写库的人做出的明智选择;它比大多数行都长,因此很有可能只需要进行一次内存分配。 (FWIW:我编写了 getline()getdelim() 的实现,用于在标准库中没有版本的机器上。它使用 256 作为最小分配(而不是 120)——除非为测试而编译,当它使用 8作为确保重新分配代码得到更多锻炼的起点。当没有足够的空间时,分配的大小会加倍。这与库设计者在您使用的库中所做的类似的思考过程;获得足够大的内存分配第一次,代码大部分不需要重新分配。)
  2. 您可以在库中找到代码,更改默认值,然后重新构建库。 OTOH,这很辛苦。
  3. 有一个名为getline() 的函数,它通过返回值告诉您刚刚读取的行中有多少字符。请注意,它在出错时返回 -1(不是 EOF)。虽然这种情况很少发生,但理论上 EOF 可能是 -1 以外的负值。

您还可以通过以下方式使系统使用较短的行(直到您阅读较长的行):

FILE *file_in;
size_t len = 16;
char *line = malloc(len);

而且(对于 sleazeball 编程的终极目标)您甚至不必检查分配错误,因为 char *line = NULL; 也是 getline() 的有效输入:

ssize_t nbytes;

while ((nbytes = getline(&line, &len, file_in)) > 0)
    ...process a line of nbytes including newline...

【讨论】:

  • 您可能会建议 OP 使用更具描述性的名称:len -> capacity(表示实际内容可能更小),nbytes -> linelen(如以及strlen() 不包括'\0')。为什么要排除0>0 而不是!=-1)?在这里不可能被一个单一的案例不阻塞或中断吗?文件结尾或错误由-1 指示。
  • @jfs:为什么要排除 0?因为在任何情况下getline() 都不能返回 0 作为有效响应。如果内存分配或 EOF 存在问题,则返回的值为-1(以及信号等)。如果它不返回EOF,那么它至少读取一个换行符,所以返回值至少是1;它不能合法地成为0 AFAICS。如果你担心的话,你可以把条件改成((bytes = …) >= 0),但是我估计不会执行零的情况。
【解决方案2】:

getline() 将根据需要扩展 len 和 realloc line,以适应读取的任何输入。

您可能还没有看到line > 120。

要获取读取的行的长度,可以使用返回值或strlen:int num_chars = strlen(line);

使用getline最简单的方法是这样的:

size_t len = 0;
char *line = 0;

while(...) {
    size_t n = get_line(&line, &len, file);
    // n is the number of chars in line, len is the total size of the line buffer.
}

getline() 将根据需要更改 linelen

*最重要的是,阅读 getline 手册页。*

【讨论】:

    【解决方案3】:

    您需要使用getline返回值

    【讨论】:

      【解决方案4】:

      来自the manual page"If *lineptr is NULL [...] the value in *n is ignored."

      “为什么是 120?”的答案是它没有意义 - 没有“为什么”,因为在这种情况下你没有使用那个值。

      使用getline的返回值来确定返回行的长度。

      【讨论】:

        猜你喜欢
        • 2012-09-21
        • 1970-01-01
        • 1970-01-01
        • 2019-11-26
        • 1970-01-01
        • 2011-10-18
        • 2022-07-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多