Pasar vector de puntero a char a las funciones[C]

Iniciado por NOB2014, 20 Junio 2016, 16:14 PM

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

NOB2014

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.

void ingreso( char *ptrFrases );
void ingreso( char ptrFrases[] );
int main( void ){
char *ptrFrases = NULL;

ingreso( ptrFrases );
ordenar( ptrFrases );
mostrar( ptrFrases );

return 0;
}
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. -

tmp = (char*)realloc( ptrFrases+i, CARACTERES * sizeof(char) );
if( tmp!=NULL ){
strcpy( ptrFrases[i-1], tmp );
}


#include <stdio.h>
#include<stdlib.h>
#include<string.h>

#define CARACTERES 21
#define safeFree(p) saferFree((void**)&(p))

void ingreso( char *ptrFrases );
void vaciarBuffer( char tmp[] );
void ordenar( char *ptrFrases );
void mostrar( char *ptrFrases );
void saferFree( void **pp );

int main( void ){
char *ptrFrases = NULL;

ingreso( ptrFrases );
ordenar( ptrFrases );
mostrar( ptrFrases );

return 0;
}


void ingreso( char *ptrFrases ){
int i = 0, ok, opc;
char tmp[CARACTERES], ch;

while( 1 ){
printf( "\n Ingrese una palabra(maximo %d caracteres).....:", CARACTERES-1 );
fgets( tmp, CARACTERES, stdin );
vaciarBuffer( tmp );

do{
printf( "\n 1 - Ingresa otra frase\n 0 - Finalisa\n Ingrese opcion...: " );
ok = scanf( "%d", &opc ) == 1 && opc >= 0 && opc <=1;
while ((ch = getchar()) != EOF && ch != '\n');
}while( !ok );
if( opc == 0){
break;
}
i++;
tmp = (char*)realloc( ptrFrases+i, CARACTERES * sizeof(char) );
if( tmp!=NULL ){
strcpy( ptrFrases[i-1], tmp );
}
else{
safeFree( ptrFrases );
puts( "Error (re)allocating memory" );
exit(1);
}
}

}

void vaciarBuffer( char tmp[] ){
char *p = NULL;
size_t ch;

if((p=strchr(tmp, '\n'))){
*p='\0';
}
else{
while((ch = getchar()) !='\n' && ch!=EOF);
}
}

void saferFree(void **pp) {
if (pp != NULL && *pp != NULL) {
free(*pp);
*pp = NULL;
}
}

void ordenar( char *ptrFrases ){
printf( "\n No desarrollado" );
}
void mostrar( char *ptrFrases ){
printf( "\n No desarrollado" );
}

Saludos y gracias. -
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.-

AlbertoBSD

#1
tmp es un vector de caractes:

char tmp[CARACTERES]

No puedes posteriormente tratar de reasignarle memoria.

tmp = (char*)realloc( ptrFrases+i, CARACTERES * sizeof(char) );

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

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.

[youtube=640,360]https://www.youtube.com/watch?v=mG8_nY3Yzg4[/youtube]

Saludos.
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

geeke

Cita de: NOB2014 en 20 Junio 2016, 16:14 PM
como se pasan los vectores de punteros a las funciones.

Con

Código (cpp) [Seleccionar]
void f(char** array_ptr);

O

Código (cpp) [Seleccionar]
void f(char* array_ptr[]);

AlbertoBSD

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

char **fraces;

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

Es decir:

ptrFrases = (char*)realloc( ptrFrases, i * sizeof(char*) );
       ptrFrases[i-1] = malloc(CARACTERES);
if( ptrFrases[i-1]!=NULL ){
strcpy( ptrFrases[i-1], tmp );
}
else{
safeFree( ptrFrases );
puts( "Error (re)allocating memory" );
exit(1);
}



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
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

NOB2014

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.

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

#include <stdio.h>
#include <stdlib.h>

int main( void ){
char **frases, *tmp;
size_t i=0;

while(i < 5){
frases = (char*)realloc( frases, i * sizeof(char*) );
tmp = calloc(20,1);
printf( "\n Ingrese frase....:" );
fgets( tmp, 20, stdin );
frases[i] = tmp;
i++;
}
i=0;
while(i < 5){
printf( "\n Frases Ingresadas....: %s", frases[i] );
i++;
}

return 0;
}

No tendrá mucha relación con el programa que quiero hacer pero trate de hacerlo sencillo para poder entenderlo. -


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

AlbertoBSD

Siempre es bueno simplificar los ejemplos para entender los conceptos.

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

Deberia de funcionar con eso.

Saludos.
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

NOB2014

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

#include <stdio.h>
#include <stdlib.h>

int main( void ){
char **frases=NULL, *tmp=NULL;
size_t i=0;

while(i < 5){
i++;
frases = (char**)realloc( frases, i * sizeof(char*) );
tmp = calloc(20,1);
printf( "\n Ingrese frase....:" );
fgets( tmp, 20, stdin );
frases[i-1] = tmp;
}
i=0;
while(i < 5){
printf( "\n Frases Ingresadas....: %s", frases[i] );
i++;
}

free(frases);

return 0;
}


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

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.

AlbertoBSD

No tiene fugas de memoria si te fijas las asigna a su variable frases.

frases[i-1] = tmp;

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

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

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

Saludos
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

NOB2014

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


#include <stdio.h>
#include <stdlib.h>

int main( void ){
char **frases=NULL;
size_t i=0;

while(i < 5){
i++;
frases = (char**)realloc( frases, i * sizeof(char*) );
frases[i-1] = calloc(20,1);
printf( "\n Ingrese frase....:" );
fgets( frases[i-1], 20, stdin );
}
i=0;
while(i < 5){
printf( "\n Frases Ingresadas....: %s", frases[i] );
free(frases[i]);
i++;
}

return 0;
}


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