Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: NOB2014 en 20 Junio 2016, 16:14 pm



Título: Pasar vector de puntero a char a las funciones[C]
Publicado por: NOB2014 en 20 Junio 2016, 16:14 pm
Hola.
Tengo una duda que deseo evacuarla ahora porque me impide seguir estudiando y es: como se pasan los vectores de punteros a las funciones.

Código
  1. void ingreso( char *ptrFrases );
Código
  1. void ingreso( char ptrFrases[] );
Código
  1. int main( void ){
  2. char *ptrFrases = NULL;
  3.  
  4. ingreso( ptrFrases );
  5. ordenar( ptrFrases );
  6. mostrar( ptrFrases );
  7.  
  8. return 0;
  9. }
  10.  
Dejo el programa por si les hace falta para interpretar mejor la duda, luego tengo que continuar consultándolos porque la siguiente linea sé que estoy haciendo todo mal pero es la primera vez que lo intento y realmente no logro solucionarlo, hacer lo mismo con números me funciona a la perfección, en cambio, con cadenas no. -

Código
  1. tmp = (char*)realloc( ptrFrases+i, CARACTERES * sizeof(char) );
  2. if( tmp!=NULL ){
  3. strcpy( ptrFrases[i-1], tmp );
  4. }
  5.  

Código
  1. #include <stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4.  
  5. #define CARACTERES 21
  6. #define safeFree(p) saferFree((void**)&(p))
  7.  
  8. void ingreso( char *ptrFrases );
  9. void vaciarBuffer( char tmp[] );
  10. void ordenar( char *ptrFrases );
  11. void mostrar( char *ptrFrases );
  12. void saferFree( void **pp );
  13.  
  14. int main( void ){
  15. char *ptrFrases = NULL;
  16.  
  17. ingreso( ptrFrases );
  18. ordenar( ptrFrases );
  19. mostrar( ptrFrases );
  20.  
  21. return 0;
  22. }
  23.  
  24.  
  25. void ingreso( char *ptrFrases ){
  26. int i = 0, ok, opc;
  27. char tmp[CARACTERES], ch;
  28.  
  29. while( 1 ){
  30. printf( "\n Ingrese una palabra(maximo %d caracteres).....:", CARACTERES-1 );
  31. fgets( tmp, CARACTERES, stdin );
  32. vaciarBuffer( tmp );
  33.  
  34. do{
  35. printf( "\n 1 - Ingresa otra frase\n 0 - Finalisa\n Ingrese opcion...: " );
  36. ok = scanf( "%d", &opc ) == 1 && opc >= 0 && opc <=1;
  37. while ((ch = getchar()) != EOF && ch != '\n');
  38. }while( !ok );
  39. if( opc == 0){
  40. break;
  41. }
  42. i++;
  43. tmp = (char*)realloc( ptrFrases+i, CARACTERES * sizeof(char) );
  44. if( tmp!=NULL ){
  45. strcpy( ptrFrases[i-1], tmp );
  46. }
  47. else{
  48. safeFree( ptrFrases );
  49. puts( "Error (re)allocating memory" );
  50. exit(1);
  51. }
  52. }
  53.  
  54. }
  55.  
  56. void vaciarBuffer( char tmp[] ){
  57. char *p = NULL;
  58. size_t ch;
  59.  
  60. if((p=strchr(tmp, '\n'))){
  61. *p='\0';
  62. }
  63. else{
  64. while((ch = getchar()) !='\n' && ch!=EOF);
  65. }
  66. }
  67.  
  68. void saferFree(void **pp) {
  69. if (pp != NULL && *pp != NULL) {
  70. free(*pp);
  71. *pp = NULL;
  72. }
  73. }
  74.  
  75. void ordenar( char *ptrFrases ){
  76. printf( "\n No desarrollado" );
  77. }
  78. void mostrar( char *ptrFrases ){
  79. printf( "\n No desarrollado" );
  80. }
  81.  
Saludos y gracias. -


Título: Re: Pasar vector de puntero a char a las funciones[C]
Publicado por: AlbertoBSD en 20 Junio 2016, 16:29 pm
tmp es un vector de caractes:

Código
  1. char tmp[CARACTERES]

No puedes posteriormente tratar de reasignarle memoria.

Código
  1. tmp = (char*)realloc( ptrFrases+i, CARACTERES * sizeof(char) );

Si quieres usarlo asi tienes que declararlo como apuntador desde el principio.

Código
  1. char *tmp = malloc(CARACTERE);


No entiendo cual es exactamente tu duda.

si es sobre el strcpy, el primer parametro es el destino de la copia y el segundo es el origen.

http://www.cplusplus.com/reference/cstring/strcpy/

Adicional a eso hice un video el dia de ayer sobre cadenas precisamente toco el tema de copiar cadenas de un buffer a otro.

mG8_nY3Yzg4

Saludos.


Título: Re: Pasar vector de puntero a char a las funciones[C]
Publicado por: geeke en 20 Junio 2016, 17:10 pm
como se pasan los vectores de punteros a las funciones.

Con

Código
  1. void f(char** array_ptr);

O

Código
  1. void f(char* array_ptr[]);


Título: Re: Pasar vector de puntero a char a las funciones[C]
Publicado por: AlbertoBSD en 20 Junio 2016, 17:41 pm
Aaa pasar el vector de apuntadores si es como te dice geeke, como no vi ningun vector de apuntadores declarado pense que era otra cosa.

Por cierto deberia de declarar el vector de fraces como

Código
  1. char **fraces;

y cada que asignes un espacio para un apuntador mas. Tambien tienes que inicializar ese Nuevo apuntador.

Es decir:

Código
  1. ptrFrases = (char*)realloc( ptrFrases, i * sizeof(char*) );
  2.       ptrFrases[i-1] = malloc(CARACTERES);
  3. if( ptrFrases[i-1]!=NULL ){
  4. strcpy( ptrFrases[i-1], tmp );
  5. }
  6. else{
  7. safeFree( ptrFrases );
  8. puts( "Error (re)allocating memory" );
  9. exit(1);
  10. }


La otra es que debes de retornat el valor del apuntador de fracea ya que si realloc cambia la posición de memoria de fraces dentro de una de las funciones la funcion main no se va a enterar y va a tener una copia antigua del apuntador.

En mi canal hice un video sobre Apuntadores dobles.

No pongo en link por que va a parecer spam

XD

Saludos


Título: Re: Pasar vector de puntero a char a las funciones[C]
Publicado por: NOB2014 en 20 Junio 2016, 21:46 pm
Hola.
Creo que nunca me costo tanto entender un tema como en este caso, tan solo para intentar avanzar me podrían decir que tengo que modificar para que no me del siguiente error.

Citar
ayp.c:11:10: warning: assignment from incompatible pointer type [enabled by default]
frases = (char*)realloc( frases, i * sizeof(char*) );

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main( void ){
  5. char **frases, *tmp;
  6. size_t i=0;
  7.  
  8. while(i < 5){
  9. frases = (char*)realloc( frases, i * sizeof(char*) );
  10. tmp = calloc(20,1);
  11. printf( "\n Ingrese frase....:" );
  12. fgets( tmp, 20, stdin );
  13. frases[i] = tmp;
  14. i++;
  15. }
  16. i=0;
  17. while(i < 5){
  18. printf( "\n Frases Ingresadas....: %s", frases[i] );
  19. i++;
  20. }
  21.  
  22. return 0;
  23. }
No tendrá mucha relación con el programa que quiero hacer pero trate de hacerlo sencillo para poder entenderlo. -


Saludos.


Título: Re: Pasar vector de puntero a char a las funciones[C]
Publicado por: AlbertoBSD en 20 Junio 2016, 21:55 pm
Siempre es bueno simplificar los ejemplos para entender los conceptos.

Recuerda que es un doble apuntador y deberia de ser doble *
Código
  1. frases = (char**)realloc( frases, i * sizeof(char*) );

Deberia de funcionar con eso.

Saludos.


Título: Re: Pasar vector de puntero a char a las funciones[C]
Publicado por: NOB2014 en 20 Junio 2016, 23:25 pm
Al fin logre que funcione, dejo el código porque además del error que me solucionaste tenía 2 más. -
El incremento de la variable i va al comienzo del bucle y no al final, creo que es porque en la primer iteración valiendo cero i no reservaría memoria. - 
Y el segundo lo producía porque no igualaba a NULL el puntero frases. -

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main( void ){
  5. char **frases=NULL, *tmp=NULL;
  6. size_t i=0;
  7.  
  8. while(i < 5){
  9. i++;
  10. frases = (char**)realloc( frases, i * sizeof(char*) );
  11. tmp = calloc(20,1);
  12. printf( "\n Ingrese frase....:" );
  13. fgets( tmp, 20, stdin );
  14. frases[i-1] = tmp;
  15. }
  16. i=0;
  17. while(i < 5){
  18. printf( "\n Frases Ingresadas....: %s", frases[i] );
  19. i++;
  20. }
  21.  
  22. free(frases);
  23.  
  24. return 0;
  25. }
  26.  

Saludos.


Título: Re: Pasar vector de puntero a char a las funciones[C]
Publicado por: geeke en 21 Junio 2016, 01:13 am
Tienes fugas de memoria en el interior del bucle en cada llamada a calloc() asignas un nuevo bloque de memoria a tmp y el anterior se pierde. Debes reservar espacio fuera del bucle o liberar en cada iteración y no olvides liberar al final en ambos casos.


Título: Re: Pasar vector de puntero a char a las funciones[C]
Publicado por: AlbertoBSD en 21 Junio 2016, 01:20 am
No tiene fugas de memoria si te fijas las asigna a su variable frases.

Código
  1. frases[i-1] = tmp;

Mas bien la variable tmp la tiene de mas pudo usar directamente.

Código
  1. frases[i-1] = calloc(20,1);

Pero es entendible que tenga esos detalles ya que apenas esta aprendiendo a usar apuntadores dobles.

Eso si solo esta liberando el apuntador a frases y no todos los apuntadores individuales.

Solo seria agregar un

Código
  1. free(frases[i]);
en el segundo while justo despues de imprirlas y antes de incrementar el contador.

Saludos


Título: Re: Pasar vector de puntero a char a las funciones[C]
Publicado por: NOB2014 en 21 Junio 2016, 02:04 am
Hola.
Bueno al fin en este día aprendí más de lo esperado, con la primer respuesta pensé que no podría nunca explicar mis dudas, pero todo se fue encaminando, muchas gracias a todos los que me ayudaron en este post.
Espero que ahora este aceptable y me quiero ver encajando todo esto en el otro programa, espero lograrlo.

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main( void ){
  5. char **frases=NULL;
  6. size_t i=0;
  7.  
  8. while(i < 5){
  9. i++;
  10. frases = (char**)realloc( frases, i * sizeof(char*) );
  11. frases[i-1] = calloc(20,1);
  12. printf( "\n Ingrese frase....:" );
  13. fgets( frases[i-1], 20, stdin );
  14. }
  15. i=0;
  16. while(i < 5){
  17. printf( "\n Frases Ingresadas....: %s", frases[i] );
  18. free(frases[i]);
  19. i++;
  20. }
  21.  
  22. return 0;
  23. }

Saludos.    


Título: Re: Pasar vector de puntero a char a las funciones[C]
Publicado por: NOB2014 en 21 Junio 2016, 16:03 pm
Hola, que tengan un muy buen día. -
Continuo con mis dudas pero ante quiero efectuar una aclaración, si consideran que esto de preguntar y preguntar, y no recurrir a un manual a buscar por mí mismo y piensan que eso es lo que debo hacer, todo ben, yo tengo mi criterio formado del porqué continuamente recurro a Uds. para evacuar mis dudas, en definitiva, si este post no tuviera respuesta lo entendería perfectamente y si me pegaran una bofetada psicológica también. -
Dicho esto pasa a consultarles sobre mis dudas.
Intento pasar el ingreso de los datos a una función y tengo (aparentemente) un solo error y esta en la siguiente linea. - 
Código
  1. ptrFrases = ingreso( frases );
Citar
ayp.c:10:2: error: invalid operands to binary & (have ‘int’ and ‘char **’)
Y la pregunta del millón, porque debo utilizar doble apuntador, tengo claro que lo que contiene la variable apuntador es una dirección de memoria y que un doble apuntador contiene la dirección de memoria de otro puntero. -

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. char ingreso( char **frases );
  5.  
  6. int main( void ){
  7. char **frases=NULL, **ptrFrases=NULL;
  8. size_t i = 0
  9.  
  10. ptrFrases = ingreso( frases );
  11.  
  12. while(i < 5){
  13. printf( "\n Frases Ingresadas....: %s", ptrFrases[i] );
  14. free(frases[i]);
  15. i++;
  16. }
  17.  
  18. return 0;
  19. }
  20.  
  21.  
  22. char ingreso( char **frases ){
  23. size_t i=0;
  24.  
  25. while(i < 5){
  26. i++;
  27. frases = (char**)realloc( frases, i * sizeof(char*) );
  28. frases[i-1] = calloc(20,1);
  29. printf( "\n Ingrese frase....:" );
  30. fgets( frases[i-1], 20, stdin );
  31. }
  32.  
  33. return **frases;
  34. }
Los dobles punteros son lo que no puedo interpretar, por lo menos en este caso. -
Saludos.


Título: Re: Pasar vector de puntero a char a las funciones[C]
Publicado por: AlbertoBSD en 21 Junio 2016, 16:17 pm
Si la funcion esta devolviendo un doble apuntador
deberia de ser:
Código
  1. char** ingreso( char **frases );

Con eso corrijes el error

Respecto a  tu duda.
Citar
Y la pregunta del millón, porque debo utilizar doble apuntador

No se exactamente por donde va la pregunta.

Pero se usa doble apuntador para darle mas sentido al programa, que el contenido que esta siendo apuntado es un vector de apuntadores. Que a su vez cada apuntadorindividual  apunta un vector de caracteres...

Es complicado pero una vez que lo pillas al 100 estarias entendiendo uno de los topics mas complicados del lenguaje.

Te dejo mi video, creo que ya te lo habia pasado en otro de mis respuestas.

BLrJnp1x--w


Título: Re: Pasar vector de puntero a char a las funciones[C]
Publicado por: NOB2014 en 21 Junio 2016, 17:33 pm
Citar
el contenido que esta siendo apuntado es un vector de apuntadores.
Ya había leído esto en alguna parte y creo que es la clave para entender los punteros dobles, en cuanto a
la solución que escribiste no me funciona, sigue sin compilar.-
Saludos.


Título: Re: Pasar vector de puntero a char a las funciones[C]
Publicado por: AlbertoBSD en 21 Junio 2016, 17:51 pm
Debes de cambiar

el prototipo de funcion.
la funcion en si
y el return no deberia de tener los 2 asteriscos.

De ahi en mas en que otra linea te da error?

Saludos



Título: Re: Pasar vector de puntero a char a las funciones[C]
Publicado por: NOB2014 en 22 Junio 2016, 14:28 pm
Hola, buen día para todos.
Como se nota en el código pude efectuar un avance pero me falta algo importante y es que no logro retomar la dirección de memoria a main del puntero frases como lo sugería Alberto.
Citar
La otra es que debes de retornat el valor del apuntador de fracea ya que si realloc cambia la posición de memoria de fraces dentro de una de las funciones la funcion main no se va a enterar y va a tener una copia antigua del apuntador.

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. void ingreso( char** );
  5.  
  6. int main( void ){
  7. char **frases=NULL;
  8.  
  9. ingreso( frases );
  10.  
  11. return 0;
  12. }
  13.  
  14. void ingreso( char** frases ){
  15. size_t i=0;
  16.  
  17. while(i < 5){
  18. i++;
  19. frases = (char**)realloc( frases, i * sizeof(char*) );
  20. frases[i-1] = calloc(20,1);
  21. printf( "\n Ingrese frase....:" );
  22. fgets( frases[i-1], 20, stdin );
  23. }
  24. i=0;
  25. while(i < 5){
  26. printf( "\n Frases Ingresadas....: %s", frases[i] );
  27. free(frases[i]);
  28. i++;
  29. }
  30. }

PD: En definitiva, lo que me falta es poder imprimir los datos ingresados desde main y no desde la función ingreso.-

Espero puedan ayudarme con esto también.
Saludos.  


Título: Re: Pasar vector de puntero a char a las funciones[C]
Publicado por: AlbertoBSD en 22 Junio 2016, 14:46 pm
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. char** ingreso( char** );
  5.  
  6. int main( void ){
  7. char **frases=NULL;
  8.  
  9. frases= ingreso( frases );
  10.       imprimir(frases);
  11. return 0;
  12. }
  13.  
  14. char** ingreso( char** frases ){
  15. size_t i=0;
  16.  
  17. while(i < 5){
  18. i++;
  19. frases = (char**)realloc( frases, i * sizeof(char*) );
  20. frases[i-1] = calloc(20,1);
  21. printf( "\n Ingrese frase....:" );
  22. fgets( frases[i-1], 20, stdin );
  23. }
  24.      return frases;
  25. }
  26.  
  27. void imprimir(char **frases){
  28. int i=0;
  29. while(i < 5){
  30. printf( "\n Frases Ingresadas....: %s", frases[i] );
  31. free(frases[i]);
  32. i++;
  33. }
  34.       free(frases);
  35. }

Saludos


Título: Re: Pasar vector de puntero a char a las funciones[C]
Publicado por: NOB2014 en 22 Junio 2016, 14:56 pm
Muy bien maestro funciona a la perfección, por si alguien quiere correr tu código como Ej. deberías agregarle el prototipo. -

Muchas gracias por tu tiempo, Saludos.