从C

时间:2017-05-04 09:59:11

标签: c string file memory-management

首先,我知道这个问题非常接近this topic,但问题措辞太差,以至于我甚至不确定它是否重复加上没有显示代码所以我认为它应该是问得好。

我正在尝试逐行读取文件,我需要在variable中特别存储一行。我已经成功地使用fgets轻松完成了这项操作,但文件的行数以及中的行数仍然存在未知即可。
我需要一种方法来正确地将内存分配给variable无论线的大小如何, 使用C而不是C ++

到目前为止,我的代码看起来像是:

allowedMemory = malloc(sizeof(char[1501])); // Checks if enough memory
if (NULL == allowedMemory)
{
    fprintf(stderr, "Not enough memory. \n");
    exit(1);
}
else
    char* res;
    res = allowedMemory;
while(fgets(res, 1500, file)) // Iterate until end of file
{
    if (res == theLineIWant) // Using strcmp instead of ==
        return res;
}

此代码的问题在于它根本不具备适应性。我正在寻找一种方法来为res分配足够的内存,这样我就不会错过line中的任何数据。

我在想这样的事情:

while ( lineContainingKChar != LineContainingK+1Char) // meaning that the line has not been fully read
// And using strcmp instead of ==
  realloc(lineContainingKChar, K + 100) // Adding memory

但我需要遍历两个FILE对象才能填充这些效率不高的变量。 任何有关如何实施此解决方案的提示或建议如何以更简单的方式执行此解决方案将不胜感激。

编辑:似乎使用getline()是最好的方法,因为这个函数分配自己需要的内存并在需要时释放它。然而,我不认为它是100%便携式的,因为我仍然不能使用它,尽管我已经包括<stdio.h>。但要进行验证,因为我的问题通常位于键盘和计算机之间。在那之前,我仍然对一个不使用POSIX兼容C的解决方案持开放态度。

1 个答案:

答案 0 :(得分:2)

getline()似乎完全符合您的要求:

  

<强> 说明

     

getdelim()函数应从流中读取,直到遇到a   与分隔符匹配的字符。

     

...

     

getline()函数应相当于getdelim()   delimiter字符等于<newline>的函数   字符。

     

...

     

<强> 实施例

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


int main(void)
{
    FILE *fp;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    fp = fopen("/etc/motd", "r");
    if (fp == NULL)
        exit(1);
    while ((read = getline(&line, &len, fp)) != -1) {
        printf("Retrieved line of length %zu :\n", read);
        printf("%s", line);
    }
    if (ferror(fp)) {
        /* handle error */
    }
    free(line);
    fclose(fp);
    return 0;
}

根据the Linux man page

  

<强>描述

     

getline()从流中读取整行,存储地址   包含文本的缓冲区为*lineptr。缓冲区为空 -   终止并包含换行符,如果找到了。

     

如果*lineptr设置为NULL*n在呼叫前设置为0,则   getline()将分配一个缓冲区来存储该行。这个缓冲区   即使getline()失败,也应该被用户程序释放。

     

或者,在致电getline()之前,*lineptr可以包含   指向malloc(3)的指针 - 分配的缓冲区*n字节大小。如果   缓冲区不足以容纳该行,getline()调整其大小   使用realloc(3),根据需要更新*lineptr*n

     

在任何一种情况下,成功通话后,*lineptr*n都会成功   更新以分别反映缓冲区地址和分配的大小。