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

Quiero leer el nombre ingresado por mi usuario usando C progtwigs.

Para esto escribí:

char name[20]; printf("Enter name: "); gets(name); 

Pero usar gets no es bueno, entonces, ¿cuál es la mejor manera?

Nunca debe usar gets (o scanf con un tamaño de cadena ilimitada) ya que eso lo abre a desbordamientos de búfer. Usa los fgets con un controlador stdin ya que te permite limitar los datos que se colocarán en tu búfer.

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

 #include  #include  #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 vaciará el rest 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; } 

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

Aquí hay un ejemplo de cómo hacer esto:

 #include  #include  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; } 

En un sistema POSIX, probablemente deba usar getline si está disponible.

También puede usar la función de los ggets dominio público de Chuck Falconer, que proporciona la syntax más cercana pero sin los problemas. (El sitio web de Chuck Falconer ya no está disponible, aunque archive.org tiene una copia , y yo hice mi propia página para los ggets ).

Encontré una solución fácil y agradable:

 char*string_acquire(char*s,int size,FILE*stream){ int i; fgets(s,size,stream); i=strlen(s)-1; if(s[i]!='\n') while(getchar()!='\n'); if(s[i]=='\n') s[i]='\0'; return s; } 

está basado en fgets pero libre de ‘\ n’ y caracteres adicionales stdin (para reemplazar fflush (stdin) que no funciona en todos los SO, útil si tienes que adquirir cadenas después de esto).

Puede usar la función scanf para leer una cadena

 scanf("%[^\n]",name); 

no sé sobre otras mejores opciones para recibir cadenas,

En sistemas BSD y Android también puedes usar fgetln :

 #include  char * fgetln(FILE *stream, size_t *len); 

Al igual que:

 size_t line_len; const char *line = fgetln(stdin, &line_len); 

La line no tiene terminación nula y contiene \n (o lo que sea que use su plataforma) al final. Se vuelve inválido después de la siguiente operación de E / S en la transmisión. Puede modificar el buffer de line devuelto.