elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Los 10 CVE más críticos (peligrosos) de 2020


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Arreglo de cadenas con memoria dinámica (realloc) lenguaje C.
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Arreglo de cadenas con memoria dinámica (realloc) lenguaje C.  (Leído 7,256 veces)
NOB2014


Desconectado Desconectado

Mensajes: 366



Ver Perfil
Arreglo de cadenas con memoria dinámica (realloc) lenguaje C.
« en: 3 Octubre 2016, 23:02 pm »

Hola a todos.
Alguien me podría decir como solucionar el siguiente error:
Citar
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.

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #define MAX_CHAR 30
  6.  
  7. void limpiar( void );
  8.  
  9. int main( void ){
  10. size_t contador=0, ch, n;
  11. char *frases=NULL, *tmpFrases=NULL, ingreso[MAX_CHAR], salir, *p=NULL;
  12.  
  13. do{
  14. limpiar();
  15. printf("\n Ingrese frase(maximo %d)....: ", MAX_CHAR);
  16. fgets( ingreso , MAX_CHAR, stdin );
  17. if((p=strchr(ingreso, '\n'))){
  18. *p='\0';
  19. }
  20. else{
  21. while((ch = getchar()) !='\n' && ch!=EOF);
  22. }
  23. contador++;
  24.  
  25. tmpFrases = (char*)realloc( frases, contador * sizeof(char) );
  26.  
  27. if( tmpFrases!=NULL ){
  28. frases=tmpFrases;
  29. frases[contador-1] = *ingreso ;
  30. }
  31. else{
  32. free( frases );
  33. puts( "Error (re)allocating memory" );
  34. exit(1);
  35. }
  36.  
  37. printf("\n Para continuar \"S\" para finalizar \"N\"....:");
  38. scanf("%c", &salir);
  39. while((ch = getchar()) !='\n' && ch!=EOF);
  40. }while ( salir != 'n' && salir != 'N' );
  41.  
  42. printf ("\n Frases introducidas.....: ");
  43. for( n=0; n < contador-1; n++ )
  44. printf( "\n %s ", frases[n] );
  45.  
  46. free( frases );
  47.  
  48.  
  49. return 0;
  50. }
  51.  
  52. void limpiar( void ){
  53. system("cls||clear");
  54. }
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 Desconectado

Mensajes: 1.603



Ver Perfil
Re: Arreglo de cadenas con memoria dinámica (realloc) lenguaje C.
« Respuesta #1 en: 4 Octubre 2016, 01:07 am »

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

Código:
char frases = calloc(frases, (tam_frases + 1) * sizeof(char*))

seguidamente cargas la nueva frase al array

Código:
scanf("%m[^\n]%*c", &frases[tam_frases]);

y actualizas tam_frases

Código:
++tam_frases

Para acabar acuérdate de liberar toda la memoria adquirida por scanf para cada cadena.
Código:
for(i = 0; i < tam_frases; ++i)
    free(cadena[i])


En línea

NOB2014


Desconectado Desconectado

Mensajes: 366



Ver Perfil
Re: Arreglo de cadenas con memoria dinámica (realloc) lenguaje C.
« Respuesta #2 en: 4 Octubre 2016, 01:37 am »

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 Desconectado

Mensajes: 93


Ver Perfil
Re: Arreglo de cadenas con memoria dinámica (realloc) lenguaje C.
« Respuesta #3 en: 4 Octubre 2016, 03:09 am »

También puedes usar array de punteros

Código
  1. char *frases[size]
  2. for (i = 0; i < size; i++)
  3.    frases[i] = malloc(len_frase * sizeof(char));
« Última modificación: 4 Octubre 2016, 04:12 am por geeke » En línea

MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: Arreglo de cadenas con memoria dinámica (realloc) lenguaje C.
« Respuesta #4 en: 4 Octubre 2016, 11:30 am »

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 Desconectado

Mensajes: 366



Ver Perfil
Re: Arreglo de cadenas con memoria dinámica (realloc) lenguaje C.
« Respuesta #5 en: 4 Octubre 2016, 12:59 pm »

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. -

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #define MAX_CHAR 30
  6.  
  7. void limpiar( void );
  8. void mostrar( char **frases, int numStrings );
  9. void liberar( char **frases, int numStrings );
  10.  
  11. int main( void ){
  12. char **frases = NULL, tmp_frase[MAX_CHAR], *p=NULL;
  13. int i, numStrings = 0, ch;
  14.  
  15. while( 1 ){
  16. limpiar();
  17. if( numStrings > 0){
  18. mostrar( frases, numStrings );
  19. }
  20. printf( "\n Introduzca una cadena (Enter para finalizar)......: ");
  21. fgets(tmp_frase, MAX_CHAR, stdin );
  22. if((p=strchr(tmp_frase, '\n'))){
  23. *p='\0';
  24. }
  25. else{
  26. while((ch = getchar()) !='\n' && ch!=EOF);
  27. }
  28.    if (strlen(tmp_frase) == 0){
  29. break;
  30.    }
  31.    frases = (char **) realloc (frases, (numStrings+1) * sizeof(char *));
  32. if( frases!=NULL ){
  33.     frases[numStrings++] = strdup(tmp_frase);
  34. }else{
  35. printf( "\n Error, no se pudo asignar memoria" );
  36. printf( "\n Pulse [Enter] para finalizar..." ); getchar();
  37. liberar( frases, numStrings );
  38. exit(1);
  39. }
  40. }
  41. liberar( frases, numStrings );
  42.  
  43. return 0;
  44. }
  45.  
  46. void limpiar( void ){
  47. system("cls||clear");
  48. }
  49.  
  50. void mostrar( char **frases, int numStrings ){
  51. int i;
  52.  
  53. printf("\n ========================= Ingresos ========================= " );
  54. for(i=0; i < numStrings; i++){
  55. printf("\n %s", frases[i]);
  56. }
  57. printf("\n ============================================================\n\n " );
  58. }
  59.  
  60. void liberar( char **frases, int numStrings ){
  61. int i;
  62. for (i=0; i < numStrings; i++){
  63. free (frases[i]);
  64. }
  65.  
  66. free (frases);
  67. }

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 Desconectado

Mensajes: 1.603



Ver Perfil
Re: Arreglo de cadenas con memoria dinámica (realloc) lenguaje C.
« Respuesta #6 en: 4 Octubre 2016, 15:44 pm »

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.

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. void limpiar( void ){
  5.    system("cls||clear");
  6. }
  7.  
  8. int main( void ){
  9.    size_t tam_frases = 0, i;
  10.    char **frases = NULL, salir;
  11.  
  12.    do {
  13.        limpiar();
  14.        frases = realloc(frases, (tam_frases + 1) * sizeof(char*));
  15.        if(!frases) {
  16.            fprintf(stderr, "\n\n *** Error al adquirir memoria ***\n\n");
  17.            exit(1);
  18.        }
  19.  
  20.        printf("\nIngrese frase....: ");
  21.        scanf("%m[^\n]%*c", &frases[tam_frases]);
  22.        ++tam_frases;
  23.  
  24.        printf("\nPara continuar \"S\" para finalizar \"N\"....: ");
  25.        scanf("%c%*[^\n]%*c", &salir);
  26.    } while(salir != 'n' && salir != 'N');
  27.  
  28.    printf ("\n Frases introducidas.....: ");
  29.  
  30.    for(i = 0; i < tam_frases; ++i)
  31.        printf("\n>> %s", frases[i]);
  32.  
  33.    for(i = 0; i < tam_frases; ++i)
  34.        free(frases[i]);
  35.  
  36.    return 0;
  37. }
« Última modificación: 4 Octubre 2016, 15:50 pm por MAFUS » En línea

dato000


Desconectado Desconectado

Mensajes: 3.034



Ver Perfil
Re: Arreglo de cadenas con memoria dinámica (realloc) lenguaje C.
« Respuesta #7 en: 4 Octubre 2016, 15:55 pm »



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 Desconectado

Mensajes: 366



Ver Perfil
Re: Arreglo de cadenas con memoria dinámica (realloc) lenguaje C.
« Respuesta #8 en: 4 Octubre 2016, 16:29 pm »


Yo que hice??? en fin, slds

http://foro.elhacker.net/programacion_cc/arreglo_de_apuntadores_vs_arreglo_comun_en_lenguaje_c-t458486.0.html
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 Desconectado

Mensajes: 1.603



Ver Perfil
Re: Arreglo de cadenas con memoria dinámica (realloc) lenguaje C.
« Respuesta #9 en: 4 Octubre 2016, 17:42 pm »

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

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Problema leyendo cadenas con memoria dinamica [solucionado]
Programación C/C++
dato000 9 7,150 Último mensaje 24 Enero 2014, 18:37 pm
por dato000
arreglo de cadenas con memoria dinamica
Programación C/C++
wolftdark 2 2,247 Último mensaje 7 Julio 2015, 03:30 am
por wolftdark
[C] Memoria dinámica. Malloc, Realloc
Programación C/C++
GGZ 1 2,893 Último mensaje 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,208 Último mensaje 26 Mayo 2016, 03:11 am
por NOB2014
Concatenar cadenas con memoria dinámica en lenguaje C.
Programación C/C++
NOB2014 3 4,536 Último mensaje 19 Junio 2016, 19:22 pm
por AlbertoBSD
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines