Autor
|
Tema: Arreglo de cadenas con memoria dinámica (realloc) lenguaje C. (Leído 7,339 veces)
|
NOB2014
Desconectado
Mensajes: 366
|
Hola a todos. Alguien me podría decir como solucionar el siguiente error: repaso.c: In function ‘main’: repaso.c:44:3: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=] printf( "\n %s ", frases[n] ); ^ Créanme que con lo tedioso que me resulta buscar la solución en inglés lo hice por un montón de páginas y no logré dar con la solución, creo que el error lo tengo en la línea 29 pero no lo logro. #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_CHAR 30 void limpiar( void ); int main( void ){ size_t contador=0, ch, n; char *frases=NULL, *tmpFrases=NULL, ingreso[MAX_CHAR], salir, *p=NULL; do{ limpiar(); printf("\n Ingrese frase(maximo %d)....: ", MAX_CHAR ); fgets( ingreso , MAX_CHAR , stdin ); if((p =strchr(ingreso , '\n'))){ *p='\0'; } else{ while((ch = getchar()) !='\n' && ch !=EOF ); } contador++; tmpFrases = (char*)realloc( frases , contador * sizeof(char) ); if( tmpFrases!=NULL ){ frases=tmpFrases; frases[contador-1] = *ingreso ; } else{ puts( "Error (re)allocating memory" ); } printf("\n Para continuar \"S\" para finalizar \"N\"....:"); while((ch = getchar()) !='\n' && ch !=EOF ); }while ( salir != 'n' && salir != 'N' ); printf ("\n Frases introducidas.....: "); for( n=0; n < contador-1; n++ ) printf( "\n %s ", frases [n ] ); return 0; } void limpiar( void ){ }
dato000 gracias por ocuparte del tema anterior. -Saludos
|
|
« Última modificación: 4 Octubre 2016, 13:00 pm por NOB2014 »
|
En línea
|
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
|
|
|
MAFUS
Desconectado
Mensajes: 1.603
|
frases no es un array de cadenas, es solo una cadena, prueba de ello es su definición: char *frases para que sea un array dinámico de frases deberías hacer char **frases después a cada frase nueva haces crecer el puntero con calloc char frases = calloc(frases, (tam_frases + 1) * sizeof(char*)) seguidamente cargas la nueva frase al array scanf("%m[^\n]%*c", &frases[tam_frases]); y actualizas tam_frases Para acabar acuérdate de liberar toda la memoria adquirida por scanf para cada cadena. for(i = 0; i < tam_frases; ++i) free(cadena[i])
|
|
|
En línea
|
|
|
|
NOB2014
Desconectado
Mensajes: 366
|
Hola, MAFUS. En mucho tiempo es la primera vez que no me resulta(tus ayudas) y además no entiendo los trozos de código que propones, por lo tanto, voy a intentarlo de otra manera, estoy desconcertado, tal vez otra propuesta me aclare las cosas. -
Un abrazo. -
|
|
|
En línea
|
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
|
|
|
geeke
Desconectado
Mensajes: 93
|
También puedes usar array de punteros char *frases[size] for (i = 0; i < size; i++) frases [i ] = malloc(len_frase * sizeof(char));
|
|
« Última modificación: 4 Octubre 2016, 04:12 am por geeke »
|
En línea
|
|
|
|
MAFUS
Desconectado
Mensajes: 1.603
|
Un array de cadenas es fijo, no podrá crecer más si así lo necesita.
En unas horas te voy a pasar un código ejecutable que pone en práctica lo que te he dicho.
|
|
|
En línea
|
|
|
|
NOB2014
Desconectado
Mensajes: 366
|
Hola, que tengan un muy buen día. - De tanto buscar encontré un Ej. que si bien estaba en c++ lo pude adaptar, este código cumple con todas mis expectativas en cuanto a lo que necesitaba sobre el tema, seria bueno que además del código de MAFUS (que deseo con muchas ansias verlo editado) alguien más de su versión de como haria lo mismo pero con otro código. - #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_CHAR 30 void limpiar( void ); void mostrar( char **frases, int numStrings ); void liberar( char **frases, int numStrings ); int main( void ){ char **frases = NULL, tmp_frase[MAX_CHAR], *p=NULL; int i, numStrings = 0, ch; while( 1 ){ limpiar(); if( numStrings > 0){ mostrar( frases, numStrings ); } printf( "\n Introduzca una cadena (Enter para finalizar)......: "); fgets(tmp_frase , MAX_CHAR , stdin ); if((p =strchr(tmp_frase , '\n'))){ *p='\0'; } else{ while((ch = getchar()) !='\n' && ch !=EOF ); } break; } frases = (char **) realloc (frases , (numStrings +1) * sizeof(char *)); if( frases!=NULL ){ frases[numStrings++] = strdup(tmp_frase); }else{ printf( "\n Error, no se pudo asignar memoria" ); liberar( frases, numStrings ); } } liberar( frases, numStrings ); return 0; } void limpiar( void ){ } void mostrar( char **frases, int numStrings ){ int i; printf("\n ========================= Ingresos ========================= " ); for(i=0; i < numStrings; i++){ } printf("\n ============================================================\n\n " ); } void liberar( char **frases, int numStrings ){ int i; for (i=0; i < numStrings; i++){ } }
Un fuerte abrazo para todos.
|
|
« Última modificación: 4 Octubre 2016, 13:18 pm por NOB2014 »
|
En línea
|
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
|
|
|
MAFUS
Desconectado
Mensajes: 1.603
|
Como verás hace uso de argumentos no tan comunes en scanf, pero con ellos obtengo el dato que quiero y además me libero de \n en el buffer, todo en la misma línea. #include <stdio.h> #include <stdlib.h> void limpiar( void ){ } int main( void ){ size_t tam_frases = 0, i; char **frases = NULL, salir; do { limpiar(); frases = realloc(frases , (tam_frases + 1) * sizeof(char*)); if(!frases) { fprintf(stderr , "\n\n *** Error al adquirir memoria ***\n\n"); } printf("\nIngrese frase....: "); scanf("%m[^\n]%*c", &frases [tam_frases ]); ++tam_frases; printf("\nPara continuar \"S\" para finalizar \"N\"....: "); scanf("%c%*[^\n]%*c", &salir ); } while(salir != 'n' && salir != 'N'); printf ("\n Frases introducidas.....: "); for(i = 0; i < tam_frases; ++i) for(i = 0; i < tam_frases; ++i) return 0; }
|
|
« Última modificación: 4 Octubre 2016, 15:50 pm por MAFUS »
|
En línea
|
|
|
|
dato000
Desconectado
Mensajes: 3.034
|
no puedo parar de reir con ese gif, siempre que lo veo me quedo mirandolo como un idiota contento. dato000 gracias por ocuparte del tema anterior. - Saludos
Yo que hice??? en fin, slds Creo que ya todo esta dicho, punteros no es mi fuerte, pero lo que tengo que añadir del codigo de MAFUS es que no es estandar esa asignación scanf("%m") y que puede variar su resultado dependiendo del compilador, pues he visto casos en los que al recibir caracter espacio o salto de linea obtiene un desbordamiento y almacena basura en un espacio de memoria aleatorio después de la primera palabra de una serie de caracteres, pues scanf se supone que es más para memoria estatica. Aunque supongo que con la extensión del estandar y las librerias apropiadas junto con un compilador actualizado ese problema seria resuelto y se usaria como un realloc verdadero.
|
|
|
En línea
|
|
|
|
NOB2014
Desconectado
Mensajes: 366
|
|
|
|
En línea
|
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
|
|
|
MAFUS
Desconectado
Mensajes: 1.603
|
La opción %m está incluida en el estándar POSIX.1-2008: http://pubs.opengroup.org/onlinepubs/9699919799/Si se usa con %ms no recogerá toda la línea ya que el modificador %s se detiene en el primer carácter en blanco. Para ello se usa el %[^\n] que recoge toda la línea hasta el final o hasta encontrarse un carácter de nueva línea. Como nota adicional el %*c al final de la cadena de control hace que se recoja el carácter de nueva línea pero no se asigne a ningún sitio, así se quita del buffer de entrada.
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Problema leyendo cadenas con memoria dinamica [solucionado]
Programación C/C++
|
dato000
|
9
|
7,213
|
24 Enero 2014, 18:37 pm
por dato000
|
|
|
arreglo de cadenas con memoria dinamica
Programación C/C++
|
wolftdark
|
2
|
2,277
|
7 Julio 2015, 03:30 am
por wolftdark
|
|
|
[C] Memoria dinámica. Malloc, Realloc
Programación C/C++
|
GGZ
|
1
|
2,931
|
19 Noviembre 2015, 01:44 am
por GGZ
|
|
|
Arreglo con memoria dinámica en lenguaje C.
« 1 2 »
Programación C/C++
|
NOB2014
|
14
|
5,304
|
26 Mayo 2016, 03:11 am
por NOB2014
|
|
|
Concatenar cadenas con memoria dinámica en lenguaje C.
Programación C/C++
|
NOB2014
|
3
|
4,592
|
19 Junio 2016, 19:22 pm
por AlbertoBSD
|
|