【问题标题】:size_t cast in getline in Csize_t 在 C 中的 getline 中强制转换
【发布时间】:2014-10-29 20:16:17
【问题描述】:

我刚刚发现gets已被弃用,并且由于可靠性问题不推荐使用scanf,所以我正在尝试getline()。

如果我声明一个 size_t 变量并为其分配要使用的字节数,我可以毫无问题地使用 getline。

我知道,如果我想让 getline 为我使用 memalloc,我必须将第二个参数(size_t * one)分配为零,并将 char ** 分配给 NULL。它有效:

int main(){
    int read;
    size_t zero = 0;
    char *A;
    A=NULL;
    printf("Write something:\n");
    read=getline(&A, &zero, stdin);
    if(read!= -1) puts(A);
    return 0;
}

如果我将零分配给变量,它可以工作,但为什么我不能像这样不声明变量并强制转换零 (0):

int main(){
    int read;
    //size_t zero = 0;
    char *A;
    A=NULL;
    printf("Write something:\n");
    read=getline(&A, (size_t *)0, stdin);
    if(read!= -1) puts(A);
    return 0;
}

最后一段代码编译正常,但是getline返回-1,所以报错。

【问题讨论】:

  • 您使用的最大长度(在好的版本中)为 0,因此不会读取任何字符。

标签: c getline size-t


【解决方案1】:

因为&size 不是空指针。它是包含 0 的对象的有效地址,这与指针为0 且不指向任何地方不同。

顺便说一句,gets 已从 C 标准中删除,但 fgets 没有。这是便携式 C 的方式。

【讨论】:

    【解决方案2】:
    this is the correct way to use getline()
    
    #include <stdio.h>
    
    int main()
    {
        int bytes_read;   // number of bytes actually read
        int nbytes = 100; // max number of bytes to read
        char *my_string;  // ptr to byte read
    
        puts ("Please enter a line of text.");
    
        /* These 2 lines are the heart of the program. */
        my_string = (char *) malloc (nbytes + 1);
        if( NULL == my_string )
        { // then error occurred with malloc
            perror( "malloc" );
            exit(1);
        }
    
        // implied else
    
        bytes_read = getline (&my_string, &nbytes, stdin);
    
        if (bytes_read == -1)
        {
            puts ("ERROR!");
        }
        else
        {
            puts ("You typed:");
            puts (my_string);
        }
    
        free( my_string );
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      您可以查看getline()manpage 以获得更好的理解。

      正如函数原型所说的

      ssize_t getline(char **lineptr, size_t *n, FILE *stream);

      有两种情况。

      1. 如果*lineptrNULL,那么getline() 自己会分配一个缓冲区来存储该行,该缓冲区需要由用户释放。在这种情况下,由于*lineptrNULL,因此缓冲区的大小(由size_t *n 表示)没有意义,它被忽略了。 getline() 处理内存分配。

      2. 如果在调用getline()之前,*lineptr包含一个指向malloc()分配的缓冲区的指针,那么我们需要告诉getline()这个缓冲区的大小,即*n 字节大小。如果缓冲区不够大,无法容纳该行,getline() 会使用realloc() 调整其大小,并使用新值更新*lineptr*n

      所以,根据你的问题

      如果我声明一个 size_t 变量并为其分配要使用的字节数,我可以毫无问题地使用 getline。

      ==> Number of bytes to use 应该是已分配缓冲区的大小(如果已分配)。

      我知道,如果我想让 getline 为我使用 memalloc,我必须将第二个参数(size_t * one)分配为零,并将 char ** 分配给 NULL。

      ==> *lineptr 应该为 NULL,对。 *n 可以保存任何值,因为它将被忽略,但 n 应该是一个有效的指针[如size_t zero = 0;&amp;zero],而不是NULL 指针[如@987654347 @],因为在成功调用 getptr() 后,*n 将更新以反映分配的大小。

      希望这会有所帮助!

      【讨论】:

        猜你喜欢
        • 2023-04-01
        • 2011-12-10
        • 1970-01-01
        • 2012-05-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多