UC3M

Grado en Ing. Telemática/Sist. Audiovisuales/Sist. de Comunicaciones

Arquitectura de Sistemas

Septiembre 2017 - Enero 2018

8.4.2. La función getline

La librería GNU ofrece la función no estándar getline que hace sencilla la lectura de líneas:

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

Esta función lee una línea entera de stream, almacenando el texto (incluyendo el carácter de nueva línea y el de terminación) en un buffer y almacenando la dirección del buffer en *lineptr. Antes de llamar a getline, tienes que colocar en *lineptr la dirección de un buffer de *n bytes de largo usando malloc. Si este buffer no es lo suficientemente grande como para albergar la frase leída, getline hace el buffer más grande usando realloc, actualizando la nueva dirección en *lineptr y el tamaño en *n. Si inicializas *lineptr a null y *n a cero, getline hace ese malloc por tí.

Si todo ha ido bien, *lineptr es un char * que apunta al texto que se ha leido. La función devuelve el número de caracteres leídos aunque sin contar el carácter '\0' de terminación (sí con el de nueva línea); si ha habido algún error o se alcanza final de fichero, devuelve -1.

Nota

Siempre que tengas que leer una línea de texto del teclado, hazlo pues con getline; te evitarás cualquier problema posterior.

El siguiente programa muestra cómo usar getline para leer una línea de texto desde teclado de manera segura. Intenta teclear más de 10 caracteres, verás que getline lo gestiona correctamente, independientemente del número de caracteres que teclees.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <stdio.h>
#define TAM_MAXIMO 10

int main(void)
{
  ssize_t bytes_leidos;
  size_t numero_bytes;
  //ssize_t y size_t son sinónimos de unsigned int
  char *cadena;

  puts("Por favor, introduce una línea de texto:\n");
  /* Puedes pasar a getline los argumentos inicializados: */
  //numero_bytes = TAM_MAXIMO;
  //cadena = (char *) malloc (numero_bytes + 1);
  //bytes_leidos = getline(&cadena, &numero_bytes, stdin);
  
  /*O bien, más sencillo, poner el número a 0 y la cadena a NULL, para que él mismo te haga
  la reserva necesaria*/
  numero_bytes = 0;
  cadena = NULL;
  bytes_leidos = getline(&cadena, &numero_bytes, stdin);

  if (bytes_leidos == -1)
  {
    puts("Error.");
  }
  else
  {
    puts("La línea es:");
    puts(cadena);
  }
  free(cadena);

  return 0;
}

Comprueba con estas preguntas si has entendido este documento.

  1. Indica la afirmación INCORRECTA respecto a la función getline:

    • Devuelve el número de caracteres leídos, incluyendo el caracter '\n' de fin de línea, pero no cuenta el '\0' de final de cadena.

    • Si el buffer de memoria que recibe como parámetro de entrada no tiene espacio suficiente, devuelve un error.

    • Si el puntero al buffer de memoria que se le pasa para guardar el resultado es NULL, reserva memoria internamente con un malloc.