¿Cómo leo una cadena ingresada por el usuario en C?

Resuelto Peeyush asked hace 14 años • 8 respuestas

Quiero leer el nombre ingresado por mi usuario usando programas en C.

Para esto escribí:

char name[20];

printf("Enter name: ");
gets(name);

Pero usarlo getsno es bueno, entonces, ¿cuál es una mejor manera?

Peeyush avatar Oct 26 '10 20:10 Peeyush
Aceptado

Nunca debes usarlo gets(o scanfcon un tamaño de cadena ilimitado) ya que eso te abre a desbordamientos del búfer. Utilice fgetscon un stdinidentificador ya que le permite limitar los datos que se colocarán en su búfer.

Aquí hay un pequeño fragmento que uso para la entrada de línea del usuario:

#include <stdio.h>
#include <string.h>

#define OK       0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
    int ch, extra;

    // Get line with buffer overrun protection.
    if (prmpt != NULL) {
        printf ("%s", prmpt);
        fflush (stdout);
    }
    if (fgets (buff, sz, stdin) == NULL)
        return NO_INPUT;

    // If it was too long, there'll be no newline. In that case, we flush
    // to end of line so that excess doesn't affect the next call.
    if (buff[strlen(buff)-1] != '\n') {
        extra = 0;
        while (((ch = getchar()) != '\n') && (ch != EOF))
            extra = 1;
        return (extra == 1) ? TOO_LONG : OK;
    }

    // Otherwise remove newline and give string back to caller.
    buff[strlen(buff)-1] = '\0';
    return OK;
}

Esto me permite establecer el tamaño máximo, detectará si se ingresan demasiados datos en la línea y también borrará el resto de la línea para que no afecte la siguiente operación de entrada.

Puedes probarlo con algo como:

// Test program for getLine().

int main (void) {
    int rc;
    char buff[10];

    rc = getLine ("Enter string> ", buff, sizeof(buff));
    if (rc == NO_INPUT) {
        // Extra NL since my system doesn't output that on EOF.
        printf ("\nNo input\n");
        return 1;
    }

    if (rc == TOO_LONG) {
        printf ("Input too long [%s]\n", buff);
        return 1;
    }

    printf ("OK [%s]\n", buff);

    return 0;
}
paxdiablo avatar Oct 26 '2010 13:10 paxdiablo

Creo que la mejor y más segura forma de leer las cadenas ingresadas por el usuario es usargetline()

A continuación se muestra un ejemplo de cómo hacer esto:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
    char *buffer = NULL;
    int read;
    unsigned int len;
    read = getline(&buffer, &len, stdin);
    if (-1 != read)
        puts(buffer);
    else
        printf("No line read...\n");

    printf("Size read: %d\n Len: %d\n", read, len);
    free(buffer);
    return 0;
}
joaopauloribeiro avatar Sep 26 '2012 17:09 joaopauloribeiro