Autor
|
Tema: Array de cadenas por teclado en C (Leído 3,036 veces)
|
Raymond Carver
Desconectado
Mensajes: 4
|
Hola, soy un principiante de programación en C (no se nada de C++) y ya me hacía falta conseguir un foro para poder despejar dudas. Les ruego tengan paciencia. La cuestión es que aprendí a hacer arrays de cadenas pero no logro que me las tome por teclado usando un solo array de caracteres, y de echo es bastante curioso el resultado que me da. Pongo el caso en que la salida es la esperada, usando tres arrays para capturar las cadenas: #include <stdio.h> int main() {char *a[2]; char letra0[50]; char letra1[50]; char letra2[50]; }
Compilo, le ingreso como datos "cadena0", "cadena1", "cadena2", y como resultado obtengo: a[0]=cadena0 a[1]=cadena1 a[2]=cadena2 Lo cual es perfectamente lo esperado. Ahora en cambio uso solo el array "letra" para capturar el ingreso, de esta forma: #include <stdio.h> int main() {char *a[2]; char letra[50]; }
Ahora compilo, le ingreso los mismo que en el caso anterior, pero el resultado es: a[0]=cadena2 a[1]=cadena2 a[2]=cadena2 O sea, en todas las posiciones de a me asignó el último ingreso. Realmente me desconcierta. Si hubiese copiado el primer ingreso, tal vez sospecharía que el problema es con el gets (de echo lo probé con scanf y pasa lo mismo), pero ¿¿¿el último??? O sea, no entiendo como al pedir el último dato, haciendo a[2]=gets(letra) puede ser que a lo que toma desde el teclado lo asigne a los tres a sin llamar a la asignación. Desde ya muchas gracias al que me ayude.
|
|
|
En línea
|
|
|
|
JorgeEMX
|
Es normal, ya que lo que está guardando gets es lo último que escribiste. En todo caso, deberías usar arreglos multidimensionales: #include <stdio.h> int main() { char letra[2][100]; printf("letra[0]=%s \n",letra [0]); printf("letra[1]=%s \n",letra [1]); printf("letra[2]=%s \n",letra [2]); }
|
|
|
En línea
|
|
|
|
Raymond Carver
Desconectado
Mensajes: 4
|
Claro, así también lo podría haber pensado, pero yo quería hacerlo con un array de cadenas y un array de caracteres. O sea, no entiendo por qué en la forma en que lo hice no lo toma. Por ejemplo, cuando hago: 1- a[0]=gets(letra); 2- a[1]=gets(letra); En 1, ¿no estaría tomando la entrada del teclado, y asignándosela a a[0]? Haciendo letra="cadena desde el teclado" a[0]=letra En 2, ¿no tomaría una segunda entrada y asignándosela a a[1]? Haciendo letra="nueva cadena desde el teclado" a[1]=letra Acá lo modifiqué un poco a lo que había echo. Lo pruebo y me muestra correctamente los datos luego de cada pedido, pero mal al final. O sea, al principio pido que se escriba "cadena0", se asigna a letra, se asigna letra a a[0], y se muestran letra y cadena[0] correctamente. Se hace eso con las tres a. Pero al final cuando las imprime todas las muestra como "cadena2" a las tres (o sea, la última entrada escrita). No llego a entender por qué reescribe las dos primeras a. #include <stdio.h> int main() {char *a[2]; char letra[50]; puts("Ingrese cadena0:"); puts("Ingrese cadena1:"); puts("Ingrese cadena2:"); puts("Ahora mostramos todos los a"); }
|
|
« Última modificación: 11 Junio 2014, 21:20 pm por Raymond Carver »
|
En línea
|
|
|
|
JorgeEMX
|
Tiene que ver con el manejo de punteros, al final... los 3 punteros de "a" terminan apuntando al mismo valor de "letra".
|
|
|
En línea
|
|
|
|
leosansan
Desconectado
Mensajes: 1.314
|
........................................
Acá lo modifiqué un poco a lo que había echo. Lo pruebo y me muestra correctamente los datos luego de cada pedido, pero mal al final. O sea, al principio pido que se escriba "cadena0", se asigna a letra, se asigna letra a a[0], y se muestran letra y cadena[0] correctamente. Se hace eso con las tres a. Pero al final cuando las imprime todas las muestra como "cadena2" a las tres (o sea, la última entrada escrita). No llego a entender por qué reescribe las dos primeras a. ...........................
Como tan acertadamente apunta JorgeEMX los tres punteros "a" apuntan a la dirección de "letra" y a medida que introduces un nuevo valor de "letra" con gets estas "actualizando" la dirección, y por tanto el valor al que apuntan, de los punteros anteriores. Lo veras mejor si imprimes el puntero del gets y los anteriores. De esa manera veras mejor como se actualizan cada vez que usas el gets los valores a los que apuntan los punteros: #include <stdio.h> int main(){ char *a[2]; char letra[50]; puts("Ingrese cadena0:"); a[0]=gets(letra); printf("a[0]=%s \n",a[0]); puts("Ingrese cadena1:"); a[1]=gets(letra); printf("a[0]=%s \n",a[0]); printf("a[1]=%s \n",a[1]); puts("Ingrese cadena2:"); a[2]=gets(letra); printf("a[0]=%s \n",a[0]); printf("a[1]=%s \n",a[1]); printf("a[2]=%s \n",a[2]); return 0; }
Ingrese cadena0: 111 a[0]=111 Ingrese cadena1: 222 a[0]=222 a[1]=222 Ingrese cadena2: 333 a[0]=333 a[1]=333 a[2]=333
Process returned 0 (0x0)
Como ves los valores se han ido actualizando en cada gets. ¡¡¡¡ Saluditos! ..... !!!!
|
|
« Última modificación: 11 Junio 2014, 23:06 pm por leosansan »
|
En línea
|
|
|
|
Raymond Carver
Desconectado
Mensajes: 4
|
Claro claro, ahora entiendo donde está el error. Cuando hago a[0]=gets(letra) no le estoy asignando al puntero el valor de "letra" (en este caso sería la cadena), sino que le estoy asignando su dirección de memoria. Son punteros, no guardan valores, guardan direcciones.
Son esas cosas que uno supuestamente ya sabe pero hasta que no se equivoca mil veces no se acostumbra a tener en cuenta.
¡Muchas gracias por ayudarme!
|
|
|
En línea
|
|
|
|
rir3760
Desconectado
Mensajes: 1.639
|
Solo para redondear el tema: 1) Cuando se declara un array se indica el numero de elementos y se accede a ellos mediante los indices 0 .. N-1 ya que en C los indices inician en cero. Con esta declaración: char *a[2];
Declaras un array de dos elementos y se accede a ellos mediante los indices 0 y 1, al utilizar en el programa "a[2]" este puede reventar (comportamiento no definido). 2) No tiene caso (ya que no hay validaciones) almacenar el valor de retorno de la función gets ya que esta retorna el argumento pasado o bien NULL en caso de error. 3) No se recomienda el uso de gets, si apenas empiezas tu aprendizaje del lenguaje C por favor lee el tema |Lo que no hay que hacer en C/C++. Nivel basico|. Un saludo
|
|
|
En línea
|
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly. -- Kernighan & Ritchie, The C programming language
|
|
|
|
|