Discussion:
problema de concepto de estructura de punteros
(demasiado antiguo para responder)
newsf@nospam_grupalia.com
2004-04-20 17:06:11 UTC
Permalink
Hola grupo, estoy haciendo un programa en el que leo los siguientes datos
datos de un fichero externo llamado "entrada.txt"
primeralinea 2
segundalinea 8
terceralinea 9
primeralinea 1
ultimalinea 7
Estos datos los meto en una estructura que dentro tiene un puntero y un
entero. Mi problema es que cuando intento recorrer lo introducido en el
puntero, me sale siempre la información de lo último que he metido.
Si sustituyo el puntro por un array todo funciona perfectamente. He creado
el siguiente programa en el que te da el resutlado con el puntero y si
comentas la líneas del puntero y descomentas las comentadas, te la el
resultado con el array.
Supongo que tengo un problema de concepto.

Alguien me puede echar una mano, gracias.
Fernando

Ejemplo:
#include <stdio.h>
#include <string.h>

main ()
{

FILE *f_in; /*fichero origen*/
char *leido, c;
int i=0, i1=0, cl=0;
struct ordenar
{
char *p_correo;
// char correo[100];
int n;
};

if ((f_in = fopen ("entrada.txt", "r")) == NULL) //Abro el fichero
{
printf ("Error de apertura del fichero entrada.txt\n");
exit (1);
}

if((leido = (char *)malloc(100 * sizeof(char))) == NULL) //Lo pongo en
memoria dinamica y compruebo que hay memoria Heap.
{
printf ("No hay mas memoria en el Heap");
exit(1);
}

do //Para contar las líneas que tiene el fichero
{
c = getc(f_in);
if (c == '\n') cl++;
}while (feof(f_in) == 0);

rewind(f_in); // Rebobino y dejo el cursor al principio del fichero.

struct ordenar linea[cl];

do
{

fgets(leido,100,f_in);

linea[i].p_correo = strtok(leido, "\t\n");
//strcpy (linea[i].correo, strtok(leido, "\t\n"));
linea[i].n = atoi(strtok(NULL, "\t\n"));


printf ("%s\t%d\ti = %d\n", linea[i].p_correo, linea[i].n, i);
//printf ("%s\t%d\ti = %d\n", linea[i].correo, linea[i].n, i);
i++;
} while (feof(f_in) == 0);


printf ("posicion 0 =%s\t%d\n", linea[0].p_correo, linea[0].n);
printf ("posicion 1 =%s\t%d\n", linea[1].p_correo, linea[1].n);
printf ("posicion 2 =%s\t%d\n", linea[2].p_correo, linea[2].n);
printf ("posicion 3 =%s\t%d\n", linea[3].p_correo, linea[3].n);
printf ("posicion 4 =%s\t%d\n", linea[4].p_correo, linea[4].n);

//printf ("posicion 0 =%s\t%d\n", linea[0].correo, linea[0].n);
//printf ("posicion 1 =%s\t%d\n", linea[1].correo, linea[1].n);
//printf ("posicion 2 =%s\t%d\n", linea[2].correo, linea[2].n);
//printf ("posicion 3 =%s\t%d\n", linea[3].correo, linea[3].n);
//printf ("posicion 4 =%s\t%d\n", linea[4].correo, linea[4].n);

}
sés
2004-04-20 17:21:57 UTC
Permalink
El problema es que no est=E1s asignando memoria a cada 'linea[i].p_corre=
o', =

solo asignas memoria UNA vez, a 'leido'.
newsf@nospam_grupalia.com
2004-04-21 09:30:15 UTC
Permalink
Siguiendo vuestras instrucciones he hecho los cambios que creo me habeis
dicho pero me sigue haciendo los mismo. Arreglaría algo que usase typedef.
Lo que quiere hacer realmente es leer un monton de líneas que tienen un
identificador y un valor. Si encuentro varias iguales, sumo su valor y borro
las demás hasta dejar solor una.
Los cambio que he hecho los reflejo aquí:
#include <stdio.h>
#include <string.h>

main ()
{

FILE *f_in; /*fichero origen*/
char *leido, c;
int i=0, i1=0, cl=0;
struct ordenar
{
char *p_correo;
int n;
};

if ((f_in = fopen ("entrada.txt", "r")) == NULL) //Abro el fichero
{
printf ("Error de apertura del fichero entrada.txt\n");
exit (1);
}

if((leido = (char *)malloc(100 * sizeof(char))) == NULL) //Lo pongo en
memoria dinamica y compruebo que hay memoria Heap.
{
printf ("No hay mas memoria en el Heap");
exit(1);
}

do //Para contar las líneas que tiene el fichero
{
c = getc(f_in);
if (c == '\n') cl++;
}while (feof(f_in) == 0);

rewind(f_in); // Rebobino y dejo el cursor al principio del fichero.

struct ordenar linea[cl];
if((linea[0].p_correo = (char *)malloc(100 * sizeof(char))) == NULL) //Lo
pongo en memoria dinamica y compruebo que hay memoria Heap.
{
printf ("No hay mas memoria en el Heap");
exit(1);
}
if((linea[1].p_correo = (char *)malloc(100 * sizeof(char))) == NULL) //Lo
pongo en memoria dinamica y compruebo que hay memoria Heap.
{
printf ("No hay mas memoria en el Heap");
exit(1);
}
if((linea[2].p_correo = (char *)malloc(100 * sizeof(char))) == NULL) //Lo
pongo en memoria dinamica y compruebo que hay memoria Heap.
{
printf ("No hay mas memoria en el Heap");
exit(1);
}
if((linea[3].p_correo = (char *)malloc(100 * sizeof(char))) == NULL) //Lo
pongo en memoria dinamica y compruebo que hay memoria Heap.
{
printf ("No hay mas memoria en el Heap");
exit(1);
}
if((linea[4].p_correo = (char *)malloc(100 * sizeof(char))) == NULL) //Lo
pongo en memoria dinamica y compruebo que hay memoria Heap.
{
printf ("No hay mas memoria en el Heap");
exit(1);
}

do
{

fgets(leido,100,f_in);


linea[i].p_correo = strtok(leido, "\t\n");

linea[i].n = atoi(strtok(NULL, "\t\n"));


printf ("%s\t%d\ti = %d\n", linea[i].p_correo, linea[i].n, i);

i++;
} while (feof(f_in) == 0);


printf ("posicion 0 =%s\t%d\n", linea[0].p_correo, linea[0].n);
printf ("posicion 1 =%s\t%d\n", linea[1].p_correo, linea[1].n);
printf ("posicion 2 =%s\t%d\n", linea[2].p_correo, linea[2].n);
printf ("posicion 3 =%s\t%d\n", linea[3].p_correo, linea[3].n);
printf ("posicion 4 =%s\t%d\n", linea[4].p_correo, linea[4].n);

free(leido);
free(linea[0].p_correo);
free(linea[1].p_correo);
free(linea[2].p_correo);
free(linea[3].p_correo);
free(linea[4].p_correo);

}


"s�s" <***@tengo.es> wrote in message news:***@127.red-80-37-166.pooles.rima-tde.net...
El problema es que no estás asignando memoria a cada 'linea[i].p_correo',
solo asignas memoria UNA vez, a 'leido'.
Antoine Leca
2004-04-21 08:42:49 UTC
Permalink
Post by ***@nospam_grupalia.com
Estos datos los meto en una estructura que dentro tiene un puntero y
un entero.
Si tienes un puntero, dendro tiene que ir la "dirección" de cada uno de los
textos de las lineas. Si siempre pones la dirección del búffer (leido), no
almacenará las informaciones. La verdad es que no hay espacio para este
almacenimiento.

Tu idea de tener una tabla en vez del puntero parecía buena. Porque una
tabla, al contrario de un puntero, sí que crea espacio. Si no quieres seguir
con ella (¿espacio?), hay que abrir otro espacio (otro malloc) para las
lineas.

No olvida de siempre liberar con free() los espacios que creas con malloc().

Antoine
newsf@nospam_grupalia.com
2004-04-21 09:30:01 UTC
Permalink
Siguiendo vuestras instrucciones he hecho los cambios que creo me habeis
dicho pero me sigue haciendo los mismo. Arreglaría algo que usase typedef.
Lo que quiere hacer realmente es leer un monton de líneas que tienen un
identificador y un valor. Si encuentro varias iguales, sumo su valor y borro
las demás hasta dejar solor una.
Los cambio que he hecho los reflejo aquí:
#include <stdio.h>
#include <string.h>

main ()
{

FILE *f_in; /*fichero origen*/
char *leido, c;
int i=0, i1=0, cl=0;
struct ordenar
{
char *p_correo;
int n;
};

if ((f_in = fopen ("entrada.txt", "r")) == NULL) //Abro el fichero
{
printf ("Error de apertura del fichero entrada.txt\n");
exit (1);
}

if((leido = (char *)malloc(100 * sizeof(char))) == NULL) //Lo pongo en
memoria dinamica y compruebo que hay memoria Heap.
{
printf ("No hay mas memoria en el Heap");
exit(1);
}

do //Para contar las líneas que tiene el fichero
{
c = getc(f_in);
if (c == '\n') cl++;
}while (feof(f_in) == 0);

rewind(f_in); // Rebobino y dejo el cursor al principio del fichero.

struct ordenar linea[cl];
if((linea[0].p_correo = (char *)malloc(100 * sizeof(char))) == NULL) //Lo
pongo en memoria dinamica y compruebo que hay memoria Heap.
{
printf ("No hay mas memoria en el Heap");
exit(1);
}
if((linea[1].p_correo = (char *)malloc(100 * sizeof(char))) == NULL) //Lo
pongo en memoria dinamica y compruebo que hay memoria Heap.
{
printf ("No hay mas memoria en el Heap");
exit(1);
}
if((linea[2].p_correo = (char *)malloc(100 * sizeof(char))) == NULL) //Lo
pongo en memoria dinamica y compruebo que hay memoria Heap.
{
printf ("No hay mas memoria en el Heap");
exit(1);
}
if((linea[3].p_correo = (char *)malloc(100 * sizeof(char))) == NULL) //Lo
pongo en memoria dinamica y compruebo que hay memoria Heap.
{
printf ("No hay mas memoria en el Heap");
exit(1);
}
if((linea[4].p_correo = (char *)malloc(100 * sizeof(char))) == NULL) //Lo
pongo en memoria dinamica y compruebo que hay memoria Heap.
{
printf ("No hay mas memoria en el Heap");
exit(1);
}

do
{

fgets(leido,100,f_in);


linea[i].p_correo = strtok(leido, "\t\n");

linea[i].n = atoi(strtok(NULL, "\t\n"));


printf ("%s\t%d\ti = %d\n", linea[i].p_correo, linea[i].n, i);

i++;
} while (feof(f_in) == 0);


printf ("posicion 0 =%s\t%d\n", linea[0].p_correo, linea[0].n);
printf ("posicion 1 =%s\t%d\n", linea[1].p_correo, linea[1].n);
printf ("posicion 2 =%s\t%d\n", linea[2].p_correo, linea[2].n);
printf ("posicion 3 =%s\t%d\n", linea[3].p_correo, linea[3].n);
printf ("posicion 4 =%s\t%d\n", linea[4].p_correo, linea[4].n);

free(leido);
free(linea[0].p_correo);
free(linea[1].p_correo);
free(linea[2].p_correo);
free(linea[3].p_correo);
free(linea[4].p_correo);

}
Post by Antoine Leca
Post by ***@nospam_grupalia.com
Estos datos los meto en una estructura que dentro tiene un puntero y
un entero.
Si tienes un puntero, dendro tiene que ir la "dirección" de cada uno de los
textos de las lineas. Si siempre pones la dirección del búffer (leido), no
almacenará las informaciones. La verdad es que no hay espacio para este
almacenimiento.
Tu idea de tener una tabla en vez del puntero parecía buena. Porque una
tabla, al contrario de un puntero, sí que crea espacio. Si no quieres seguir
con ella (¿espacio?), hay que abrir otro espacio (otro malloc) para las
lineas.
No olvida de siempre liberar con free() los espacios que creas con malloc().
Antoine
Antoine Leca
2004-04-21 10:48:11 UTC
Permalink
Post by ***@nospam_grupalia.com
Siguiendo vuestras instrucciones he hecho los cambios que creo me
habeis dicho pero me sigue haciendo los mismo.
¿Cúando copias desde "leido" hasta la memoria que has creado? strtok no hace
ninguna copia, la debes hacer tú, con algún strcpy.

¡Cuidado con el número de caracteres que puede escribir fgets!


Antoine
newsf
2004-04-21 11:55:20 UTC
Permalink
Con ese último funciona correctamente.

Lo de tener que asignar el espacio a cada puntero, supongo que lo podría
hacer con un bucle, ya que tengo sobre unos 15000 punteros que asignar.
Estos punteros tiene unos 255 caracteres (ya que como no se cual es el
tamaño de ellos le he puesto ese valor), con lo que me puede ocupar cerca de
4 MB. Como memoria RAM no es mucho y supongo que no debe de haber ningún
problema.
¿A que te refieres con que tenga cuidado con fgets?

Gracias,
Fernando
Post by Antoine Leca
Post by ***@nospam_grupalia.com
Siguiendo vuestras instrucciones he hecho los cambios que creo me
habeis dicho pero me sigue haciendo los mismo.
¿Cúando copias desde "leido" hasta la memoria que has creado? strtok no hace
ninguna copia, la debes hacer tú, con algún strcpy.
¡Cuidado con el número de caracteres que puede escribir fgets!
Antoine
Antoine Leca
2004-04-21 12:47:22 UTC
Permalink
Post by newsf
Lo de tener que asignar el espacio a cada puntero, supongo que lo
podría hacer con un bucle, ya que tengo sobre unos 15000 punteros que
asignar. Estos punteros tiene unos 255 caracteres (ya que como no se
cual es el tamaño de ellos le he puesto ese valor), con lo que me
puede ocupar cerca de 4 MB.
Hagues el llamamiento a malloc despues del fgets, sabiendo el largo de la
cadena de carácteres. No olvides el '\0'.
Post by newsf
Como memoria RAM no es mucho y supongo
que no debe de haber ningún problema.
No tenemos los mismos criterios. ;-)
Post by newsf
¿A que te refieres con que tenga cuidado con fgets?
Que fgets escribe un '\0' al final de la linea, además de los carácteres que
has mandado. Entonces hay que preguntar por un carácter menos que la cadena
que recibirá.


Antoine

Loading...