Ç - 获取下一行 [英] C - Get next line

查看:134
本文介绍了Ç - 获取下一行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(我只是授权使用:malloc的,免费的,读)

我试图让与任何BUF_SIZE文件中的下一行,但它的返回我错误的值。

因此,返回(错误值,缺少首创字符)值:

  3
1 - #包括LT&;&stdio.h中GT;
1 - dlib.h>
1 - CLUDElibft / libft.h
1 - 32 BUFF_SIZE

我的源$ C ​​$ C:

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&fcntl.h GT;
#包括libft / libft.h
#定义BUFF_SIZE 32INT get_next_line(INT FD常量,字符**行)
{
    字符缓冲区[BUFF_SIZE + 1];
    为size_t我;
    为size_t的大小;    如果(!(*线=的malloc(BUFF_SIZE)))
        返回(-1);
    *行[0] ='\\ 0';
    而(读(FD,缓冲器,BUFF_SIZE)大于0)
    {
        缓冲[BUFF_SIZE + 1] ='\\ 0';
        如果(缓冲[0] =='\\ n')
            返回(1);
        如果(ft_strchr(缓冲区的'\\ n')!= NULL)
        {
            I = 0;
            大小= ft_strlen(*行);
            缓冲[BUFF_SIZE + 1] ='\\ 0';
            而(缓冲[I]!='\\ 0')
            {
                如果(缓冲[I] =='\\ n')
                {
                    如果(!(*行= realloc的(*线,I +大小)))
                        返回(-1);
                    缓冲[I] ='\\ 0';
                    ft_strncat(*线,缓冲液,一);
                    返回(1);
                }
                我++;
            }
        }
        如果(!(*行= realloc的(*线,BUFF_SIZE)))
            返回(-1);
        ft_strncat(*线,缓冲液,BUFF_SIZE);
    }
    返回(0);
}INT主要(无效)
{
    INT的fd;
    INT RET;
    字符*线;    如果((FD =打开(main.c中,O_RDONLY))3;放大器;&安培;!FD = 0)
        返回(-1);
    的printf(%d个\\ N,FD);
    RET = get_next_line(FD,&安培;线);
    的printf(%d个 - %S \\ n,RET线);
    RET = get_next_line(FD,&安培;线);
    的printf(%d个 - %S \\ n,RET线);
    RET = get_next_line(FD,&安培;线);
    的printf(%d个 - %S \\ n,RET线);
    RET = get_next_line(FD,&安培;线);
    的printf(%d个 - %S \\ n,RET线);
    返回(0);
}


解决方案

我得到这个由他们string.h中等价更换所有的ft_blah功能进行编译。有很多问题。

在C字符串是空终止,因此需要分配给他们为空一个额外的字节。如果你想分配单个字符的字符串,你必须分配两个字节。

接下来最大的问题是你一直要追加到 TMP ,但它只有分配一个字节。 TMP 需要有分配给它,当您去更多的内存。

在内存分配的主题,缓存永远不会回来,所以没有必要在堆中分配的内存吧。它可以简单地在堆栈,而不是自动free'd函数返回时。 字符缓冲区[2] =

您应该使用 strncat函数,而不是的strcpy ,连接字符串。

这似乎 ft_strverif 只是复制字符串?我不知道你为什么打电话之前把它叫做的strcpy ,将刚才复制的字符串。 的strcpy(TMP,ft_strverif(缓冲)); 办法缓存不必要地复制两次。更糟的是,这些额外的副本从来free'd因此它会导致内存泄漏。

我建议取消 TMP 完全和,而不是直接追加到。使用的realloc 来添加更多的内存,可能是最好的块中添加内存或效率每次加倍。

如果你模仿函数getline 注意,函数getline 需要已分配行缓冲区的长度是有原因的。这让而(函数getline ...)循环重复使用而不必fre​​e'd每个循环迭代。实际上,成为一个可重用的缓冲。

最后,总是以 -Wall 甚至 -Weverything 运行,如果你的编译器支持它。修正的所有的警告,即使他们看起来很可笑。然后,使用运行code 的valgrind ,它会在你使用未初始化的内存,或者告诉你你在哪里再泄漏内存。非常,非常有帮助。

一旦所有这样做了, get_next_line 变得简单多了。

  INT get_next_line(INT常量的fd,字符**行)
{
    炭缓冲液[2] =;    / *如果需要分配内存行* /
    如果(!*行)
        *线=的malloc(100 * sizeof的(炭));    / *空出一行* /
    *行[0] ='\\ 0';    而(读(FD,缓冲液,1)大于0){
        strncat函数(*线,缓冲液,1);
        如果(缓冲[0] =='\\ n')
            打破;
    }    返回0;
}

留给你的练习...


  • 防范四溢

  • 请不要使用一个静态的大小

  • get_next_line 增长需要。

  • 让对方有多么大是(如函数getline 一样)。

( I'm just authorized to use: malloc, free, read)
I'm trying to get the next line in a file with any BUF_SIZE but it's returning me the wrong value.
So, the returned (wrong value, missing firsts chars) value:

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

My source code:

#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);
}

解决方案

I got this to compile by replacing all the ft_blah functions with their string.h equivalents. There are many problems.

Strings in C are null terminated and so need an extra byte allocated to them for that null. If you want to allocate a string of a single character, you have to allocate two bytes.

Next big problem is you keep trying to append to tmp but it only has a single byte allocated. tmp needs to have more memory allocated to it as you go.

On the theme of memory allocation, buffer is never returned so there's no need to allocate memory for it on the heap. It can simply on the stack instead and automatically free'd when the function returns. char buffer[2] = "".

You should be using strncat, not strcpy, to concatenate strings.

It seems ft_strverif just copies the string? I don't know why you call it before calling strcpy which will just copy the string. strcpy(tmp, ft_strverif(buffer)); means buffer is needlessly copied twice. Worse, that extra copy is never free'd so it will leak memory.

I'd suggest eliminating tmp entirely and instead append directly to line. Use realloc to add more memory to line, probably best to add memory in chunks or double it every time for efficiency.

If you're emulating getline note that getline takes the length of the already allocated line buffer for a reason. This lets line be reused in the while(getline...) loop without having to be free'd every loop iteration. In effect, line becomes a reusable buffer.

Finally, always run with -Wall or even -Weverything if your compiler supports it. Fix all the warnings, even if they seem silly. Then, run your code using valgrind, it will tell you when you're using uninitialized memory or where you're leaking memory. Very, very helpful.

Once all that's done, get_next_line becomes much simpler.

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;
}

The exercises left for you are...

  • Protect against overflowing line.
  • Don't use a static size for line.
  • Make get_next_line grow line as needed.
  • Let the caller know how large line is (like getline does).

这篇关于Ç - 获取下一行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆