C - 下一行

时间:2016-02-08 14:50:02

标签: c file

(我只是被授权使用:malloc,免费,阅读)
我尝试使用任何BUF_SIZE获取文件中的下一行但是它返回了错误的值。
所以,返回的(错误值,缺少第一个字符)值:

3
1 - #include <stdio.h>
1 - dlib.h>
1 - clude "libft/libft.h"
1 - BUFF_SIZE  32

我的源代码:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include "libft/libft.h"
# define BUFF_SIZE  32

int     get_next_line(int const fd, char **line)
{
    char buffer[BUFF_SIZE + 1];
    size_t i;
    size_t size;

    if (!(*line = malloc(BUFF_SIZE)))
        return (-1);
    *line[0] = '\0';
    while (read(fd, buffer, BUFF_SIZE) > 0)
    {
        buffer[BUFF_SIZE + 1] = '\0';
        if (buffer[0] == '\n')
            return (1);
        if (ft_strchr(buffer, '\n') != NULL)
        {
            i = 0;
            size = ft_strlen(*line);
            buffer[BUFF_SIZE + 1] = '\0';
            while (buffer[i] != '\0')
            {
                if (buffer[i] == '\n')
                {
                    if (!(*line = realloc(*line, i + size)))
                        return (-1);
                    buffer[i] = '\0';
                    ft_strncat(*line, buffer, i);
                    return (1);
                }
                i++;
            }
        }
        if (!(*line = realloc(*line, BUFF_SIZE)))
            return (-1);
        ft_strncat(*line, buffer, BUFF_SIZE);
    }
    return (0);
}

int     main(void)
{
    int     fd;
    int     ret;
    char    *line;

    if ((fd = open("main.c", O_RDONLY)) < 3 && fd != 0)
        return (-1);
    printf("%d\n", fd);
    ret = get_next_line(fd, &line);
    printf("%d - %s\n", ret, line);
    ret = get_next_line(fd, &line);
    printf("%d - %s\n", ret, line);
    ret = get_next_line(fd, &line);
    printf("%d - %s\n", ret, line);
    ret = get_next_line(fd, &line);
    printf("%d - %s\n", ret, line);
    return (0);
}

1 个答案:

答案 0 :(得分:0)

我通过将所有ft_blah函数替换为其string.h等价来编译。有很多问题。

C中的字符串以空值终止,因此需要为该空值分配一个额外的字节。如果要分配单个字符的字符串,则必须分配两个字节。

接下来的一个大问题是你一直试图追加到tmp,但它只分配了一个字节。 <{1}}需要在你去的时候分配更多的内存。

关于内存分配的主题,永远不会返回tmp,因此不需要在堆上为它分配内存。它可以简单地在堆栈上,并在函数返回时自动释放。 buffer

您应该使用char buffer[2] = ""而不是strncat来连接字符串。

似乎strcpy只复制字符串?在调用ft_strverif之前,我不知道为什么要调用它,这只会复制字符串。 strcpy表示strcpy(tmp, ft_strverif(buffer));被不必要地复制两次。更糟糕的是,额外的副本永远不会免费,因此会泄漏内存。

我建议完全取消buffer,而是直接附加到tmp。使用linerealloc添加更多内存,可能最好以块的形式添加内存,或者每次都加倍内存以提高效率。

如果您正在模仿line,请注意getline因为某种原因而占用已分配的行缓冲区的长度。这使得getline可以在line循环中重复使用,而不必每次循环迭代都是自由的。实际上,while(getline...)成为可重用的缓冲区。

最后,如果编译器支持,则始终使用line-Wall运行。修复所有警告,即使它们看起来很傻。然后,使用valgrind运行您的代码,它将告诉您何时使用未初始化的内存或您正在泄漏内存的位置。非常非常有帮助。

完成所有这些后,-Weverything变得更加简单。

get_next_line

留给你的练习是......

  • 防止溢出int get_next_line(int const fd, char **line) { char buffer[2] = ""; /* Allocate line memory if needed */ if( !*line ) *line = malloc(100 * sizeof(char)); /* Blank out the line */ *line[0] = '\0'; while( read(fd, buffer, 1) > 0 ) { strncat(*line, buffer, 1); if( buffer[0] == '\n' ) break; } return 0; }
  • 请勿使用line的静态大小。
  • 根据需要让line成长get_next_line
  • 让来电者知道line有多大(就像line那样)。