2014-10-29 2 views
0

Я только что узнал, что получение устарело, а scanf не рекомендуется из-за проблем с надежностью, поэтому я пытаюсь getline().size_t cast in getline in C

Я могу использовать getline без проблем, если объявить переменную size_t и присвоить ей количество используемых байтов.

Я понимаю, что если я хочу 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

Максимальная длина использования (в хорошей версии) равна 0, поэтому никакие символы (символы) не будут прочитаны. – user3629249

ответ

1

Потому что &size не является нулевым указателем. Это действительный адрес объекта , содержащий0, который отличается от указателя 0 и указывает в никуда.

BTW, gets был удален из стандарта C, но fgets не было. Это путь для портативного C.

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

Вы можете посмотреть на manpage из getline(), чтобы получить лучшее понимание.

В качестве функции prototye говорит

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

Есть два случая.

  1. Если *lineptr является NULL, то getline() сам по себе будет выделить буфер для хранения линии, которая должна быть освобождена пользователем. В этом случае, поскольку *lineptr равен NULL, нет никакого значения размера буфера (обозначается size_t *n) и его игнорируется. getline() обрабатывает выделение памяти.

  2. Если перед вызовом getline(), *lineptr содержит указатель на malloc() -allocated буфера, то мы должны сказать, размер буфера getline(), то есть *n байт. В случае, если буфер недостаточно велик для удержания линии, getline() изменяет размер его realloc(), обновляя *lineptr и *n с новыми значениями.

Таким образом, в соответствии с вашим вопросом

я могу использовать GetLine без проблем, если я объявить size_t переменную и присвоить ему число байтов для использования.

==>Number of bytes to use должен быть размером выделенного буфера (если выделено).

Я понимаю, что если я хочу getline для memalloc для меня, я должен присвоить второй параметр (size_t * one) равным нулю, а char ** - NULL.

==>*lineptr должно быть NULL, справа. *n может занимающее какую-либо ценность, как оно будет проигнорировано, но n должен быть непросроченный указатель [как в случае size_t zero = 0; и &zero], а не NULL указатель [как в случае (size_t *)0], потому что, после успешного вызова getptr(), *n будет обновлен с учетом выделенного размера.

Надеюсь, что это поможет!