scanf y gets

Iniciado por m@o_614, 17 Julio 2013, 02:37 AM

0 Miembros y 3 Visitantes están viendo este tema.

m@o_614

saludos

si tengo que ingresar en un vector 10 datos, por ejemplo: nombres, estos nombres tienen diferente longitud entonces tendria que poner char *nombre[10] pero a la hora de querer ingresar los datos con gets me aparecen warnings

for(i=0;i < 10;i++)
    {
        printf("Dame el nombre numero %d: ",i+1);
        gets(nombre+i);
        system("cls");
    }


pero si cambio el gets por scanf de esta manera ya no me aparece y no entiendo porque

for(i=0;i < 10;i++)
    {
        printf("Dame el nombre numero %d: ",i+1);
        scanf("%s",nombre+i);
        system("cls");
    }


si alguien fuera tan amable de explicarme esto se lo agradeceria mucho

amchacon

Pues sin saber el tipo de variable y sin ver el warning no te podemos ayudar mucho.

Eso sí, gets está anticuada y no está recomendada su uso. En su lugar es preferible usar fgets:
http://www.cplusplus.com/reference/cstdio/fgets/

Que vendría a ser:
fgets(nombre,10,stdin); // Leer del teclado 10 caracteres y meterlos en nombre
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

m@o_614

saludos amchacon el tipo de dato es char *arreglo[10] y el warning dice:

passing argument 1 of gets from incompatible pointer type

esto en la linea
gets(nombre+i);

y tambien sale una nota que dice expected char* but argument is of type char**

gracias

eferion

*arreglo[10] es un vector de punteros... equivalente ( que no igual ) a **arreglo, es decir, "char**"

si tu en una instrucción pones "nombre + i"... el tipo resultante sigue siendo char**, que es incompatible con el que espera gets ( char* )

Para resolver eso tienes que quitar un nivel de indirección en el puntero, es decir, pasar de un puntero doble a un puntero simple.

¿De qué manera has definido la variable "arreglo"?

Sin más información es complicado darte una explicación más acertada.

aguml

gets(*nombre[i*10]);

Aunque es solo una suposicion porque sin ver la declaracion...

m@o_614

eferion como es eso de que *arreglo[10] es equivalente a **arreglo???

m@o_614

y otra duda tambien de un vector de punteros

por ejemplo si tengo

char *meses[3] ={"Enero","Febrero","Marzo"};
for(i=0;i < 3;i++)
    printf("%s",*meses+i);



aqui me imprime Enero Nero Ero

pero si a la linea del printf le agrego unos parentesis
printf("%s",*(meses+i));

me imprime correctamente Enero Febrero Marzo

no entiendo por que
     

eferion

Cita de: m@o_614 en 17 Julio 2013, 21:32 PM
y otra duda tambien de un vector de punteros

por ejemplo si tengo

char *meses[3] ={"Enero","Febrero","Marzo"};
for(i=0;i < 3;i++)
    printf("%s",*meses+i);



aqui me imprime Enero Nero Ero

pero si a la linea del printf le agrego unos parentesis
printf("%s",*(meses+i));

me imprime correctamente Enero Febrero Marzo

no entiendo por que
     

Si tu dibujas el mapa de memoria tendrás que lo que el vector se encuentra estructurado así ( cada letra una posición de memoria ):

'E' 'n' 'e' 'r' 'o' '\0' 'F' 'e' 'b' 'r' 'e' 'r' 'o' '\0' 'M' 'a' 'r' 'z' 'o' '\0'

y dado que "meses" es una matriz de cadena de caracteres, se cumple que:

*meses es igual a *meses + 0 y apunta al primer carácter ( 'E' ).
*meses + 1 es un desplazamiento de una posición respecto a *meses, es decir,  apunta al segundo carácter ( 'n' )
*meses + 2 es un desplazamiento de dos posiciones respecto a *meses, es decir,  apunta al tercer carácter ( 'e' )
...

Es decir, primero resuelves el puntero *meses y luego incrementas la posición apuntada.

Con esto, si intentas imprimir las cadenas resultantes te sale:

Enero, nero, ero, ro, o, (nada), Febrero, ebrero, ...

Sin embargo, *( meses + i ) es equivalente a moverte primero una fila y apuntar al caracter que esté en esa posición, de tal forma que:

*(meses + 0) o *meses apunta a 'E'
*(meses + 1) apunta a 'F'
*(meses + 2) apunta a 'M'

Al final el cambio viene promovido porque los paréntesis cambian el orden en el que se ejecutan las operaciones... no es lo mismo resolver un puntero doble y luego incrementar su posición que incrementar un puntero doble y resolver su posición.

m@o_614

Muchas gracias eferion por tus respuestas ahora ya me quedo claro, solo es cuestion de repasar las prioridades de los operadores (),[],*,+, etc...


Una ultima pregunta cuando yo declaro un arreglo de punteros char *a[5]; para despues con un for ingresarle cada uno de los elementos (a+1),(a+2),etc..., primero tengo que asignarle memoria dinamica con malloc, calloc ???

Caster

#9
Cita de: m@o_614 en 18 Julio 2013, 20:23 PM
Una ultima pregunta cuando yo declaro un arreglo de punteros char *a[5]; para despues con un for ingresarle cada uno de los elementos (a+1),(a+2),etc..., primero tengo que asignarle memoria dinamica con malloc, calloc ???

Si, esto seria asi:

a[i] = (char *) malloc(n * sizeof(char));

Y para ingresar cada elemento con un bucle for:

int i;
for (i=0; i<5; i++)
    {
        scanf("%s", a[i]);
    }