Kredns
Usando el siguiente código:
char *name = malloc(sizeof(char) + 256);
printf("What is your name? ");
scanf("%s", name);
printf("Hello %s. Nice to meet you.\n", name);
Un usuario puede ingresar su nombre, pero cuando ingresa un nombre con un espacio como Lucas Aardvark
, scanf()
simplemente corta todo después Lucas
. como hago scanf()
permitir espacios
SVA
Este ejemplo utiliza un scanset invertido, por lo que scanf sigue tomando valores hasta que encuentra un ‘\n’– nueva línea, por lo que también se guardan espacios.
#include <stdio.h>
int main (int argc, char const *argv[])
{
char name[20];
// get up to buffer size - 1 characters (to account for NULL terminator)
scanf("%19[^\n]", name);
printf("%s\n", name);
return 0;
}
-
Cuidado con los desbordamientos de búfer. Si el usuario escribe un “nombre” con 50 caracteres, el programa probablemente fallará.
– brunoais
29 de enero de 2013 a las 15:17
-
Como sabe el tamaño del búfer, puede usar
%20[^\n]s
para evitar desbordamientos de búfer– osvein
11/11/2017 a las 20:52
-
45 puntos y nadie señaló el evidente culto de carga de tener
s
¡allí!– Antti Haapala — Слава Україні
27 de junio de 2019 a las 5:39
-
no sabía sobre
fgets()
. En realidad parece más fácil de usar entoncesscanf()
. +1– Kredns
8 de agosto de 2009 a las 6:37
-
Si solo desea obtener una línea del usuario, es más fácil. También es más seguro ya que puede evitar desbordamientos de búfer. La familia scanf es realmente útil para convertir una cadena en cosas diferentes (como cuatro caracteres y un int, por ejemplo, con “%c%c%c%c%d”) pero, incluso entonces, debería usar fgets y sscanf, no scanf, para evitar la posibilidad de desbordamiento del búfer.
– pax diablo
8 de agosto de 2009 a las 6:48
-
Puede poner el tamaño máximo del búfer en formato scanf, simplemente no puede poner el tiempo de ejecución calculado sin construir el formato en tiempo de ejecución (no existe el equivalente de * para printf, * es un modificador válido para scanf con otro comportamiento: suprimir la asignación ).
– Un programador
8 de agosto de 2009 a las 11:55
-
@JonathanKomar y cualquier otra persona que lea esto en el futuro: si tu profesor te dijera que tienes que usar
scanf
en una tarea, se equivocaron al hacerlo, y puedes decirles que lo dije, y si quieren discutir conmigo al respecto, mi dirección de correo electrónico se encuentra fácilmente en mi perfil.– zwol
30 de abril de 2019 a las 18:10
-
@Rainning: no está destinado a ser hermoso, de lo contrario no tendríamos
strcscnp
oatoi
. Es un nombre funcional probablemente destinado a indicargets
desde un identificador de archivo. Su capacidad para hacer lo que quería el OP no se ve afectada de ninguna manera por su nombre.– pax diablo
14 de marzo a las 10:04
Vitim.es
Puedes usar esto
char name[20];
scanf("%20[^\n]", name);
O esto
void getText(char *message, char *variable, int size){
printf("\n %s: ", message);
fgets(variable, sizeof(char) * size, stdin);
sscanf(variable, "%[^\n]", variable);
}
char name[20];
getText("Your name", name, 20);
-
No probé, pero según otras respuestas en esta misma página, creo que el tamaño de búfer correcto para scanf en su ejemplo sería:
scanf("%19[^\n]", name);
(todavía +1 para la respuesta concisa)– DrBeco
12 de junio de 2015 a las 1:12
-
Solo como una nota al margen,
sizeof(char)
es por definición siempre 1, por lo que no hay necesidad de multiplicar por él.– pax diablo
22 de marzo de 2016 a las 7:37
-
@paxdiablo No creo que esto sea cierto para todas las arquitecturas/plataformas
– Vitim.es
27 de febrero de 2021 a las 23:50
-
@Vitim.us: si te refieres a mi
sizeof(char) == 1
comentario, es obligatorio por el estándar. Véase, por ejemplo,C11 6.5.3.4 /4
: “Cuandosizeof
se aplica a un operando que tiene tipochar
,unsigned char
osigned char
(o una versión calificada del mismo) el resultado es1
“. Algunas personas cometen el error de que, desdesizeof
devuelve el número de bytes en un tipo/variable, un 16 bitschar
dará dos. Pero ese no es el caso, ya que el estándar no define “byte” como ocho bits, sino que lo define como “una secuencia contigua de bits, cuyo número está definido por la implementación”.– pax diablo
28 de febrero de 2021 a las 1:26
Ahora parte de POSIX, sin embargo.
También soluciona el problema de asignación de búfer sobre el que preguntó anteriormente, aunque debe solucionarlo. free
ing la memoria.
-
No probé, pero según otras respuestas en esta misma página, creo que el tamaño de búfer correcto para scanf en su ejemplo sería:
scanf("%19[^\n]", name);
(todavía +1 para la respuesta concisa)– DrBeco
12 de junio de 2015 a las 1:12
-
Solo como una nota al margen,
sizeof(char)
es por definición siempre 1, por lo que no hay necesidad de multiplicar por él.– pax diablo
22 de marzo de 2016 a las 7:37
-
@paxdiablo No creo que esto sea cierto para todas las arquitecturas/plataformas
– Vitim.es
27 de febrero de 2021 a las 23:50
-
@Vitim.us: si te refieres a mi
sizeof(char) == 1
comentario, es obligatorio por el estándar. Véase, por ejemplo,C11 6.5.3.4 /4
: “Cuandosizeof
se aplica a un operando que tiene tipochar
,unsigned char
osigned char
(o una versión calificada del mismo) el resultado es1
“. Algunas personas cometen el error de que, desdesizeof
devuelve el número de bytes en un tipo/variable, un 16 bitschar
dará dos. Pero ese no es el caso, ya que el estándar no define “byte” como ocho bits, sino que lo define como “una secuencia contigua de bits, cuyo número está definido por la implementación”.– pax diablo
28 de febrero de 2021 a las 1:26
Cristóbal
no usar scanf()
para leer cadenas sin especificar un ancho de campo. También debe verificar los valores devueltos en busca de errores:
#include <stdio.h>
#define NAME_MAX 80
#define NAME_MAX_S "80"
int main(void)
{
static char name[NAME_MAX + 1]; // + 1 because of null
if(scanf("%" NAME_MAX_S "[^\n]", name) != 1)
{
fputs("io error or premature end of line\n", stderr);
return 1;
}
printf("Hello %s. Nice to meet you.\n", name);
}
Alternativamente, utilice fgets()
:
#include <stdio.h>
#define NAME_MAX 80
int main(void)
{
static char name[NAME_MAX + 2]; // + 2 because of newline and null
if(!fgets(name, sizeof(name), stdin))
{
fputs("io error\n", stderr);
return 1;
}
// don't print newline
printf("Hello %.*s. Nice to meet you.\n", strlen(name) - 1, name);
}
Tenga en cuenta que más idiomático es ‘malloc(sizeof(char) * 256 + 1)’, o ‘malloc(256 + 1)’, o incluso mejor (asumiendo que ‘name’ se usará estrictamente localmente) ‘char name[256+1]’. El ‘+1’ puede actuar como un mnemotécnico para el terminador nulo, que debe incluirse en la asignación.
–Barry Kelly
8 de agosto de 2009 a las 4:47
@Barry – Sospecho
sizeof(char) + 256
fue un error tipográfico.– Chris Lutz
20 de julio de 2011 a las 22:06