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. -
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.
Cita de: NOB2014 en 20 Junio 2016, 16:14 PM
como se pasan los vectores de punteros a las funciones.
Con
void f(char** array_ptr);
O
void f(char* array_ptr[]);
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
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.
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.
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.
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.
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
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.
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. -
ptrFrases = ingreso( frases );
Citarayp.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. -
#include <stdio.h>
#include <stdlib.h>
char ingreso( char **frases );
int main( void ){
char **frases=NULL, **ptrFrases=NULL;
size_t i = 0
ptrFrases = ingreso( frases );
while(i < 5){
printf( "\n Frases Ingresadas....: %s", ptrFrases[i] );
free(frases[i]);
i++;
}
return 0;
}
char ingreso( char **frases ){
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 );
}
return **frases;
}
Los dobles punteros son lo que no puedo interpretar, por lo menos en este caso. -
Saludos.
Si la funcion esta devolviendo un doble apuntador
deberia de ser:
char** ingreso( char **frases );
Con eso corrijes el error
Respecto a tu duda.
CitarY 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.
[youtube=640,360]https://www.youtube.com/watch?v=BLrJnp1x--w[/youtube]
Citarel 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.
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
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.
CitarLa 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.
#include <stdio.h>
#include <stdlib.h>
void ingreso( char** );
int main( void ){
char **frases=NULL;
ingreso( frases );
return 0;
}
void ingreso( char** frases ){
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++;
}
}
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.
#include <stdio.h>
#include <stdlib.h>
char** ingreso( char** );
int main( void ){
char **frases=NULL;
frases= ingreso( frases );
imprimir(frases);
return 0;
}
char** ingreso( char** frases ){
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 );
}
return frases;
}
void imprimir(char **frases){
int i=0;
while(i < 5){
printf( "\n Frases Ingresadas....: %s", frases[i] );
free(frases[i]);
i++;
}
free(frases);
}
Saludos
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.