C/Visual C - Estructuras dinámicas.

 
Vista:
sin imagen de perfil

Estructuras dinámicas.

Publicado por Sebastián (31 intervenciones) el 14/02/2017 04:37:10
Hola con todos, me gustaría si me puedan ayudar con la siguiente consulta:

Como puedo trabajar con estructuras dinámicas para n valores,
por ejemplo tengo la siguiente estructura:
1
2
3
4
5
6
7
8
9
10
11
typedef struct
{
	char *nombre1;
	char *nombre2;
	char *apellido1;
	char *apellido2;
	char cedula[10];
	char *provincia;
	char *ciudad;
	char *canton;
}info_votante;

y un puntero a la misma que sera: info_votante *punt;

Necesito almacenar n valores hasta que el usuario desee, en este como deberia hacer , para que la estructura almacena los n valores?

Muchas gracias de antemano
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil

Estructuras dinámicas.

Publicado por Sebastián (31 intervenciones) el 14/02/2017 23:57:19
Gracias por la info!, la verdad ese tema aun no le he visto pero intentare hacerlo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Estructuras dinámicas.

Publicado por Chema (234 intervenciones) el 15/02/2017 00:58:05
Las listas enlazadas son un "vicio malévolo", tanto que muchos programadores las usan para todo y las convierten en su martillo de oro.
https://es.wikipedia.org/wiki/Martillo_de_oro

Un sencillo ejemplo sin usar listas enlazadas.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/*
*Ejemplos,Técnica y C
*http://xchemax.blogspot.com.es/
*/
typedef enum E_info{nombre1,nombre2,apellido1,
apellido2,cedula,provincia,ciudad,canton,LAST_INFO}E_info;
 
typedef struct info_votante{
	char *votante[LAST_INFO];
	char buf[50 *LAST_INFO];
}info_votante;
 
typedef struct DataBase{
	info_votante **ptr;
	info_votante **end;
	info_votante **data;
}DataBase;
 
typedef struct Info_{
	int id;
	char *name;
}Info_;
 
Info_ Info[LAST_INFO]= {
	{nombre1,"nombre1"},
	{nombre2, "nombre2"},
	{apellido1,"apellido1"},
	{apellido2,"apellido2"},
	{cedula,"cedula"},
	{provincia,"provincia"},
	{ciudad,"ciudad"},
	{canton,"canton"}
};
 
char *leyen[] ={
	"SUPERBASE 1.1\nEl Sistema de informacion Electoral "
	"Numero 1 del mundo mundial\n"
	"\nOpciones\nIniciar 1\nsalir 2\n",
	"\n------\nOpciones \nVer Ultima entrada 1\nListar"
	"base 2\nsalir 3\n Cualquier otra tecla continua....\n"
};
 
DataBase *dbase;
 
void PrintInfo(info_votante *iv){
	int i;
	for( i = 0; i<LAST_INFO; i++){
		printf("%s.....\t%s\n",Info[i].name, iv->votante[i]);
	}
}
 
void InitDataBase(int n){
	dbase = malloc( sizeof(DataBase));
	dbase->data = malloc(n * sizeof(info_votante*));
	dbase->ptr = dbase->data ;
	dbase->end = (dbase->data +n);
}
 
void AddToDbase(info_votante *iv){
	int size;
 
	if(dbase->ptr >= dbase->end){
		size = dbase->end - dbase->data;
		dbase->data = realloc(dbase->data,(size + size)* sizeof(info_votante*) );
		dbase->ptr = dbase->data + size ;
		dbase->end = dbase->data  + (size + size);
	}
 
	*dbase->ptr = iv;
	dbase->ptr++;
}
 
void ListDBase(){
	info_votante **raw;
 
	raw = dbase->data;
	while(raw < dbase->ptr){
		PrintInfo(*raw);
		raw++;
		printf("\n*********\n" );
	}
}
 
void FreeAll(){
	info_votante **tmp ;
	info_votante *iv;
	int i;
	int size;
 
	size =  dbase->ptr - dbase->data;
	tmp = dbase->data;
	for ( i = 0; i < size; i++){
		iv = *tmp;
		free(iv);
		tmp++;
	}
 
	free(dbase->data);
	free(dbase);
}
 
int Init(void){
	int i;
	char c;
	char buf[50];
	int size;
	int len;
	int stop = 0;
	info_votante *iv;
 
	memset(buf, 0,50);
 
 
	while(1){
		/*
		*el bucle for() es reentrante.
		*una forma de "limpiar" la ultima linea y evitar
		*que la primera lectura de fgets() en el bucle for() sea falsa.
		*/
		fgets(buf,50,stdin);
		iv = malloc(sizeof(info_votante));
		AddToDbase(iv);
		size = 0;
 
		for( i = 0; i<LAST_INFO; i++){
			printf(":%s.....\t", Info[i].name);
			fgets(buf,50,stdin);
			len = strlen(buf);
			if(len >= 50 -2){
				printf("Te has pasado de la raya\n" );
				len = 1;
			}
			iv->votante[i] = iv->buf +size;
			memcpy(iv->buf +size,buf,len-1);
			size += len;
			iv->buf[size]= 0x0;
		}
		printf("%s",leyen[1] );
		c = getchar();
		switch(c){
			case '1':
				PrintInfo(iv);
				break;
			case '2':
				ListDBase();
				break;
			case '3':
				stop = 1;
				break;
			default:
				break;
		}
 
		if(stop == 1)
			break;
	}
 
	FreeAll();
 
	return 0;
}
 
int main(void){
	char c;
 
	printf("%s",leyen[0] );
	c = getchar();
 
	switch(c){
		case '1':
			InitDataBase(1);
			Init();
			break;
		case '2':
			break;
		case '3':
			break;
		default:
			break;
		}
 
	return 0;
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 296
Bronce
Ha mantenido su posición en C/Visual C (en relación al último mes)
Gráfica de C/Visual C

Estructuras dinámicas.

Publicado por agustin (272 intervenciones) el 15/02/2017 19:55:58
Chema supongo que no has intentado compilar tu código porque veo cosas que lo haría imposible.
La verdad es que en tu código me pierdo y no se exactamente que intentas. ¿podrías corregirlo para hacerlo funcional y poder ver su funcionamiento en un depurador? ¿que nombre tiene lo que usas para sustituir el uso de listas enlazadas en este caso?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Estructuras dinámicas.

Publicado por Tom (615 intervenciones) el 15/02/2017 22:08:18
En mi opinión, lo que hace Chema es, simplemente, un array de punteros de tamaño variable complicado, quizás, con fines didácticos.
Para según que cosas las listas enlazadas son mejores (de nuevo en mi opinión) aunque solo sea por simplicidad del código (por ejemplo, solucionas con un único malloc() por entrada lo que Chema hace con dos y además son generalmente más rápidas de ordenar al tener que mover menos cantidad de memoria)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Estructuras dinámicas.

Publicado por Chema (234 intervenciones) el 16/02/2017 00:06:36
Estimado agustin. No me vuelvas "loco", no soy un "corta y pega" el código que presento es original y creación propia, siempre compila y en este caso además VALGRIN OK, comprobado sobre un bucle de 10.000 estructuras, por el tema del realloc.

Estimado Tom, Mira bien el código y verás cosas muy interesantes.

Estructura propuesta por sebastian.

1
2
3
4
5
6
7
8
9
10
11
typedef struct
{
	char *nombre1;
	char *nombre2;
	char *apellido1;
	char *apellido2;
	char cedula[10];
	char *provincia;
	char *ciudad;
	char *canton;
}info_votante;

Para crearla hacen falta 8 lamadas a malloc.

1
2
3
4
typedef struct info_votante{
	char *votante[LAST_INFO];
	char buf[50 *LAST_INFO];
}info_votante;

La misma estructura se crea con un solo malloc.


El enunciado permite nombrar la matriz exactamente igual que una estrucctura.
1
typedef enum E_info{nombre1,nombre2,apellido1, apellido2,cedula,provincia,ciudad,canton,LAST_INFO}E_info;


1
info_votante[nombre1].....

Opinas que el código tiene fines didacticos,un poco si,pero no del todo, veo que no
le "pillas" la tecnica.

El código funciona como una lista enlazada con la ventaja de usar menos punteros, menos malloc y
lo más importante, al usar (**punteros) se puede ordenar,y manipular muy fácilmente,

Comentas que: las listas "además son generalmente más rápidas de ordenar al tener que mover menos cantidad de memoria"

¿Mas que una matriz de **punteros?, Yo creo que no.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Estructuras dinámicas.

Publicado por Chema (234 intervenciones) el 16/02/2017 00:40:13
La lista enlazada es muy útil cuando no conoces el tamaño.
Si conoces el tamaño. una matriz basta.

Trabajo con volúmenes de datos muy altos. Una de mis muchas restricciones, son las listan enlazadas,(y malloc, no me puedo permitir el lujo de hacer miles y miles de malloc) solo las uso en muy contadas ocasiones y siempre después de intentar conocer el "tamaño" por anticipado o crear distintos formatos de bufer para lidiar con tamaños variables.

dice el refranero que " lo que no mata engorda" , evitar en la medida de lo posible listas enlazadas me vuelve muy creativo, original y lo más interesante la técnica mejora y los dolores de cabeza también.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 296
Bronce
Ha mantenido su posición en C/Visual C (en relación al último mes)
Gráfica de C/Visual C

Estructuras dinámicas.

Publicado por agustin (272 intervenciones) el 16/02/2017 01:37:23
Cierto que compila, no lo mire bien y ahora veo cosas que no entiendo que hacen.
Una es ¿que finalidad tiene usar typedef con un enum en tu código? No veo que lo uses más en el código.
Por otro lado ¿que hace esto?
1
2
3
4
5
6
7
8
9
10
Info_ Info[LAST_INFO]= {
	{nombre1,"nombre1"},
	{nombre2, "nombre2"},
	{apellido1,"apellido1"},
	{apellido2,"apellido2"},
	{cedula,"cedula"},
	{provincia,"provincia"},
	{ciudad,"ciudad"},
	{canton,"canton"}
};
No tengo ni idea de que haces aquí. Yo entiendo que nombre1 es igual que poner 0 y "nombre1" es una cadena pero no veo que indiques el tipo de dato y aun así compila
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Estructuras dinámicas.

Publicado por Diego (150 intervenciones) el 16/02/2017 03:07:49
No soy el mas a decuado, pero suponindo algo lueog de leer el codigo supongo que tenes que verlo completo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
typedef struct Info_{
 
	int id;
 
	char *name;
 
}Info_;
 
 
 
Info_ Info[LAST_INFO]= {
 
	{nombre1,"nombre1"},
 
	{nombre2, "nombre2"},
 
	{apellido1,"apellido1"},
 
	{apellido2,"apellido2"},
 
	{cedula,"cedula"},
 
	{provincia,"provincia"},
 
	{ciudad,"ciudad"},
 
	{canton,"canton"}
 
};

En mi opinion es un vector con N elementos al que le esta pasando los 2 valores necesarios para inicializarlos.
1
2
3
4
5
6
7
typedef struct Info_{
 
	int id;
 
	char *name;
 
}Info_;

en este caso id y name; (int, char *).


Esa es la noción que tengo en este momento.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Estructuras dinámicas.

Publicado por Tom (615 intervenciones) el 16/02/2017 10:07:39
Por cada entrada, tienes que hacer malloc() para la estructura de datos, y realloc() para el array de punteros, el resto son accesorios.
En tu código:
1
2
iv = malloc(sizeof(info_votante)); (línea 124)
dbase->data = realloc(dbase->data,(size + size)* sizeof(info_votante*) ); (línea 67)

En una lista enlazada, solamente tendrías que hacer malloc de la estructura de datos (que incluye un puntero a la siguiente, o anterior).
Para insertar (no añadir) un nuevo elemento en un array, probablemente acabes desplazando una gran parte del array, y en una lista enlazada, solamente intercambiarás un par de punteros.

Lo de pillar "tu técnica" ¿ Te refieres a que no haces malloc() por cada atributo del votante ? Bueno, para gustos, colores, en todo caso la estructura de los datos no debería influir en la estructura de la lista que utilices (lo que sí es determinante es el conjunto de casos de uso posteriores).
Ya que usas un límite de 50 caracteres por atributo no veo nada grave que ya los reserves directamente (vale, tú ahorras un poco de espacio al usar solamente el necesario, pero también añades un puntero adicional ...)

1
2
3
4
5
6
7
8
9
struct Votante {
  char nombre[50];
  unsigned cod_postal;
  ...
};
 
...
struct Votante *iv = malloc(sizeof(struct Votante));
fgets(iv->nombre, 50, stdin);

En mi opinión, y coincide con la tuya por lo que has dicho, no hay un solución que siempre sea la mejor. En este caso concreto, puedes hacer una implementación que "ahorre" memoria, o una que "ahorre" tiempo de CPU ... o una que premita la posterior explotacion de los datos de forma sencilla, o bien de forma complicada ... :D
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Estructuras dinámicas.

Publicado por Chema (234 intervenciones) el 16/02/2017 12:14:05
Estimado Toni, no es fácil comprender el código que realizo, no lo hago adrede, es mi forma normal de trabajo.
¿El código expuesto lo consideráis complicado?, pues yo creo es un juguete realizado en 1 hora.

Toni lo de la "tecnica" veo que sigues sin entenderlo, No es mi "técnica", es solo técnica, para valorar el ejemplo en justa medida, debes apreciarlo
de otra manera, viendo los matices, la idea y sus posibles aplicaciones.

Pondremos un ejemplo para que Toni vea más posibilidades de realizar la misma operación de diferente manera y quizás asimile mejor lo de la "técnica".


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
 
typedef enum E_Data{nombre,apellido,ciudad,provincia,LAST_INFO}E_Data;
 
typedef struct DataStr{
	char *index[LAST_INFO];
	char buf[50 *LAST_INFO];
}DataStr;
 
typedef struct DataSorpresa{
	char nombre[50];
	char apellido[50];
	char ciudad[50];
	char provincia[50];
}DataSorpresa;
 
char *dataName[LAST_INFO]={
	"nombre","apellido","ciudad","provincia"
};
 
 
int main(void){
	int i;
	int x;
	int size;
	int index = 1;
	DataStr **dstr;
	//~ DataStr *tmp;
	char str[124];
	int len;
	char **ptr;
 
	dstr = malloc(2 * sizeof(DataStr*));
 
	for( i = 0; i < 2; i++){
		dstr[i] = malloc(sizeof(DataStr));
		size = 0;
		ptr = dstr[i]->index;
		for(x = 0; x < LAST_INFO; x++){
			*ptr = dstr[i]->buf + size;
			len = snprintf(str ,124,"%s = %d    ", dataName[x],index );
			memcpy(*ptr , str,len);
			size += 50;
			ptr++;
			index++;
		}
	}
 
	printf("-------PUNTERO--------------\n");
	for( i = 0; i < 2; i++){
		ptr = dstr[i]->index;
		for(x = 0; x < LAST_INFO; x++){
			 printf("%s\n", *ptr);
			 ptr++;
		}
		printf("\n");
	}
	printf("---------PUNTERO CON NOMBRE------------\n");
 
	for( i = 0; i < 2; i++){
		ptr = dstr[i]->index;
		 printf("nombre......%s\n", ptr[nombre]);
		 printf("apellido....%s\n", ptr[apellido]);
		 printf("ciudad......%s\n", ptr[ciudad]);
		 printf("provincia...%s\n", ptr[provincia]);
		printf("\n");
	}
 
	printf("--------SORPRESA-------------\n");
	DataSorpresa *sorpresa;
 
	for( i = 0; i < 2; i++){
		sorpresa = (DataSorpresa*)dstr[i]->buf;
		 printf("nombre......%s\n", sorpresa->nombre);
		 printf("apellido....%s\n", sorpresa->apellido);
		 printf("ciudad......%s\n", sorpresa->ciudad);
		 printf("provincia...%s\n", sorpresa->provincia);
	}
	return 0;
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar