zoukankan      html  css  js  c++  java
  • Linux C getline, gets, fgets 函数区别

    getline, gets, fgets都支持从标准输入读取一行字符串,那么它们有什么区别呢?
    解答:

    1. gets 不推荐使用,gets(s) 等价于 fgets(s, INT_MAX, stdin),因为没有对缓冲区溢出做处理,不安全;
    2. getline 碰到EOF返回-1,fgets返回NULL;
    3. 传入getline的buffer指针如果为NULL,函数会分配缓冲区用于存储行字符串,并由调用者释放。如果传入buffer空间不足以存放一行,那么函数会自动扩增缓冲区空间,同时更新其指针及缓冲区大小。
      传入fgets的buffer空间如果不足以存放一行,fgets提前返回,并在末尾添加null byte('')。

    getline

    getline有2个版本:getline和getdelim。

    getline原型

    #include <stdio.h>
    
    ssize_t getline(char **lineptr, size_t *n, FILE *stream);
    ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream);
    

    getline从stream(流)读取一整行字符串,存放到缓冲区buffer,并将buffer地址存储到指针lineptr。其中,buffer以空字符('')结尾,并且包含换行符。
    如果在调用getline之前,
    lineptr被设置为NULL,n被设置为0,getline()将会分配(new/malloc)一个buffer用于存储一行文本。该buffer应该由调用者释放,即使getline调用失败。
    如果在调用getline之前,buffer不够大,getline()会用realloc重新分配其大小,同时更新
    lineptr和*n。

    也就是说,getline存放一行字符串的buffer可以由调用者提供,也可以由函数分配;然而,释放都是由调用者进行。

    DESCRIPTION
           getline()  reads  an entire line from stream, storing the address of the buffer containing the text
           into *lineptr.  The buffer is null-terminated and includes the newline character, if one was found.
    
           If *lineptr is set to NULL and *n is set 0 before the call, then getline() will allocate  a  buffer
           for storing the line.  This buffer should be freed by the user program even if getline() failed.
    
           Alternatively,  before  calling  getline(), *lineptr can contain a pointer to a malloc(3)-allocated
           buffer *n bytes in size.  If the buffer is not large enough to hold the line, getline() resizes  it
           with realloc(3), updating *lineptr and *n as necessary.
    
           In either case, on a successful call, *lineptr and *n will be updated to reflect the buffer address
           and allocated size respectively.
    
           getdelim() works like getline(), except that a line delimiter other than newline can  be  specified
           as  the  delimiter  argument.  As with getline(), a delimiter character is not added if one was not
           present in the input before end of file was reached.
    
    RETURN VALUE
           On success, getline() and getdelim() return the number of characters read, including the  delimiter
           character,  but  not  including the terminating null byte ('').  This value can be used to handle
           embedded null bytes in the line read.
    
           Both functions return -1 on failure to read a line (including end-of-file condition).  In the event
           of an error, errno is set to indicate the cause.
    

    getline使用示例

    来自getline page

    int
    main(int argc, char *argv[])
    {
        FILE *stream;
        char *line = NULL;
        size_t len = 0;
        ssize_t nread;
    
        printf("hello main
    ");
    
        if (argc != 2) {
            fprintf(stderr, "Usage: %s <file>
    ", argv[0]);
            exit(EXIT_FAILURE);
        }
    
        stream = fopen(argv[1], "r");
        if (stream == NULL) {
            perror("fopen");
            exit(EXIT_FAILURE);
        }
    
        while ((nread = getline(&line, &len, stream)) != -1) {
            printf("Retrieved line of length %zu:
    ", nread);
            fwrite(line, nread, 1, stdout);
        }
    
        free(line);
        fclose(stream);
        exit(EXIT_SUCCESS);
    }
    

    gets

    符合C89, C99, POSIX.1-2001.,不过目前已经弃用,推荐使用fgets
    gets(s)相当于fgets(s, INT_MAX, stdin) + 替换末尾换行符为''。不过,这样并不不安全,因为gets不会检查s是否会溢出。

    fgets

    fgets原型

    #include <stdio.h>
    
    char *fgets(char *s, int size, FILE *stream);
    

    fgets最多从指定stream流读取 size-1个字符,并且存储到s指向的buffer中。读取遇到EOF或换行符停止。每读取一行,buffer末尾会自动添加''。

    fgets() reads in at most one less than size characters from stream and
    stores them into the buffer pointed to by s. Reading stops after an
    EOF or a newline. If a newline is read, it is stored into the buffer.
    A terminating null byte ('') is stored after the last character in
    the buffer.

    也就是说,fgets存放一行字符串的buffer必须是由调用者提供,fgets不会分配任何存储字符串的空间。

  • 相关阅读:
    选择
    随便写了一个CodeToDbTable可生成(含备注)sql脚本(基于hibernate实体)
    分享一个k8s的mysql-router配置
    因为一个外接国外项目要求英文,故用python简单写的中文页面文件转英文
    thinkpad e450 win7黑苹果macos 10.10.5(网/显/声卡驱动)安装成功
    爆栈之前端工程化技术小结(备案)
    使用Pytorch实现简单的人脸二分类器
    链表的反转
    合唱队
    字节跳动——机器人跳跃问题
  • 原文地址:https://www.cnblogs.com/fortunely/p/14590273.html
Copyright © 2011-2022 走看看