Dev - C++ - Problema con archivo binario

   
Vista:

Problema con archivo binario

Publicado por Emanuel (2 intervenciones) el 16/08/2017 04:29:54
Hola a todos!

Tengo este ejercicio en Dev-C++ que no logro concluir por qué no responde.

Para empezar, tenemos un archivo binario que se llama "aeronaves.dat", donde se deben ingresar aeronaves de tipo struct a través de C++, y luego ordenar por algunos atributos de esta estructura (id, matricula, etc.). Al principio la idea era ésta, pero luego el profesor pidió que se agregara lo siguiente: "Tomando como base esta plantilla de algoritmo, incorporar al programa gestor de aeronaves la posibilidad de buscar por identificador:"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template <typename T, typename K> int busquedaBinaria(FILE* f, K v, int (*criterio)(T, K)) {
	int i = 0;
	int j = fileSize<T>(f) - 1;
	int k = (i + j) / 2;
	seek<T>(f, k);
	T r = read<T>(f);
	while (i <= j && criterio(r, v) != 0 ) {
		if (criterio(r, v) > 0 ) {
			j = k - 1;
		} else {
			if (criterio(r, v) < 0 ) {
				i = k + 1;
			}
		}
		k = (i + j) / 2;
		r = read<T>(f);
	}
	return i <= j?k:-1;
}

El problema no es este algoritmo, sino al querer buscar cierta aeronave por su "id".

Les dejo el código hecho, es bastante largo, el problema se encuentra dentro del
1
main()
, línea 117:
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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <time.h>
using namespace std;
 
const int N_AERONAVES = 10;
int n;
 
struct Aeronave {
	int id;
	char matricula[10];
	char nombre[10];
	int hsDeVuelo;
	int fechaBaja;
};
 
void cargar(Aeronave[]);
void activos(Aeronave[]);
void guardar(Aeronave[]);
void activos();
void generarLotePorMil(Aeronave[]);
int criterioHsDeVuelo(Aeronave, Aeronave);
void mostrarAeronave(Aeronave);
int criterioMatricula(Aeronave, Aeronave);
int criterioId(Aeronave, Aeronave);
 
template <typename T> void ordenar(T arr[], int len, int (*criterio)(T, T)) {
	bool ordenado = false;
	while (!ordenado){
		ordenado = true;
		for (int i = 0; i < len - 1; i++){
			if (criterio(arr[i], arr[i + 1]) > 0 ){
				T aux = arr[i];
				arr[i] = arr[i+1];
				arr[i + 1] = aux;
				ordenado = false;
			}
		}
	}
}
 
template <typename T> void mostrar(T arr[], int len, void (*mostrarFila)(T)) {
	for (int i = 0; i < len; i++){
		mostrarFila(arr[i]);
	}
}
 
template <typename T> long fileSize(FILE* f) {
	long curr = ftell(f);
	cout << "1er salida de ftell " << curr << endl;
	fseek(f, 0, SEEK_END);
	long ultimo = ftell(f);
	cout << "Salida al final luego de SEEK_END " << ultimo << endl;
	fseek(f, curr, SEEK_SET);
	cout << "Tamanio del registro: " << sizeof(T) << endl;
	return ultimo / sizeof(T);
}
 
template <typename T> void seek(FILE* arch, int n) {
	fseek(arch, n * sizeof(T), SEEK_SET);
}
 
template <typename T> T read(FILE* f) {
	T buff;
	fread(&buff, sizeof(T), 1, f);
	return buff;
}
 
template <typename T, typename K> int busquedaBinaria(FILE* f, K v, int (*criterio)(T, K)) {
	int i = 0;
	int j = fileSize<T>(f) - 1;
	int k = (i + j) / 2;
	seek<T>(f, k);
	T r = read<T>(f);
	while (i <= j && criterio(r, v) != 0 ) {
		if (criterio(r, v) > 0 ) {
			j = k - 1;
		} else {
			if (criterio(r, v) < 0 ) {
				i = k + 1;
			}
		}
		k = (i + j) / 2;
		r = read<T>(f);
	}
	return i <= j?k:-1;
}
 
int main() {
	long a = 0, b = 0;
	Aeronave aeronave[N_AERONAVES];
	generarLotePorMil(aeronave);
	// Ejercicio 1
	//cargar(aeronave);   --> Esta funcion no se usa <--
 
	activos(aeronave);
	//a = time(NULL);
 
	// Ejercicio 2
 
 
	activos();
	//b = time(NULL);
	cout << "La diferencia de procesamiento es " << b - a << endl;
 
	cout << "Aeronaves ordenadas por Horas de vuelo: " << endl;
	ordenar<Aeronave>(aeronave, N_AERONAVES, criterioHsDeVuelo);
	mostrar<Aeronave>(aeronave, N_AERONAVES, mostrarAeronave);
 
	cout << "Aeronaves ordenadas por Matricula: " << endl;
	ordenar<Aeronave>(aeronave, N_AERONAVES, criterioMatricula);
	mostrar<Aeronave>(aeronave, N_AERONAVES, mostrarAeronave);
	guardar(aeronave);
 
	Aeronave a1;
	a1.id = 6;
 
//	ordenar<Aeronave>(aeronave, N_AERONAVES, criterioId);
	FILE* f = fopen("aeronaves.dat", "rb+");
	int q = busquedaBinaria<Aeronave, Aeronave>(f, a1, criterioId);
	cout << endl;
	mostrarAeronave(aeronave[q]);
	fclose(f);
	return 0;
}
 
void cargar(Aeronave a[]) {
	cout << "Ingrese la cantidad de aeronaves a cargar: " << endl;
	cin >> n;
 
	for (int i = 0; i < n; i++) {
		cout << "Ingrese el id de la aeronave " << i + 1 << ": " << endl;
		cin >> a[i].id;
		cout << "Ingrese la matricula de la aeronave " << i + 1 << ": " << endl;
		cin >> a[i].matricula;
		cout << "Ingrese el nombre de la aeronave " << i + 1 << ": " << endl;
		cin >> a[i].nombre;
		cout << "Ingrese las horas de vuelo de la aeronave " << i + 1 << ": " << endl;
		cin >> a[i].hsDeVuelo;
		cout << "Ingrese la fecha de baja de la aeronave " << i + 1 << ": " << endl;
		cin >> a[i].fechaBaja;
	}
}
 
void generarLotePorMil(Aeronave a[]) {
	for (int i = 0; i < N_AERONAVES; i++) {
		a[i].id = i;
		//a[i].matricula = 'A';
		//a[i].nombre = "FX 5-00";
		a[i].hsDeVuelo = i*43 % 67;
		a[i].fechaBaja = i % 5;
		n++;
	}
	a[0].matricula[0] = 'F';
	a[1].matricula[0] = 'T';
	a[2].matricula[0] = 'A';
	a[3].matricula[0] = 'Z';
	a[4].matricula[0] = 'A';
	a[5].matricula[0] = 'C';
	a[6].matricula[0] = 'C';
	a[7].matricula[0] = 'U';
	a[8].matricula[0] = 'O';
	a[9].matricula[0] = 'B';
}
 
void activos(Aeronave a[]) {
	for (int i = 0; i < n; i++) {
		if (a[i].fechaBaja == 0) {
			cout << "Aeronave " << i + 1 << ": matricula "  << a[i].matricula << endl << "y horas de vuelo "
			 << a[i].hsDeVuelo << endl;
		}
	}
}
 
void guardar(Aeronave a[]) {
	FILE *f = fopen("aeronaves.dat", "wb+");
 
	for (int i = 0; i < n; i++) {
		fwrite(&a[i], sizeof(Aeronave), 1, f);
	}
 
	fclose(f);
}
 
void activos() {
	FILE *f = fopen("aeronaves.dat", "rb+");
	Aeronave a;
	fread(&a, sizeof(Aeronave), 1, f);
 
	cout << endl << "Matriculas y horas de vuelos en actividad: "<<endl;
	while (!feof(f)) {
		if (a.fechaBaja == 0) {
			cout << a.matricula << "	" << a.hsDeVuelo << endl;
		}
		fread(&a, sizeof(Aeronave), 1, f);
	}
 
	fclose(f);
}
 
int criterioHsDeVuelo(Aeronave a, Aeronave b) {
	return a.hsDeVuelo - b.hsDeVuelo;
}
 
void mostrarAeronave(Aeronave a) {
	cout << a.id << "	" << a.nombre << "	" << a.matricula << "	" << a.fechaBaja << "	" << a.hsDeVuelo << endl;
}
 
int criterioMatricula(Aeronave a, Aeronave b) {
	for (int i = 0; i < N_AERONAVES; i++) {
		if (a.matricula[i] > b.matricula[i]) {
			return 1;
		}
		if (a.matricula[i] < b.matricula[i]) {
			return -1;
		}
	}
 
	return 0;
}
 
int criterioId(Aeronave a, Aeronave b) {
	return a.id - b.id;
}

Al querer saber, por ejemplo, la información de la aeronave 6 sí muestra, con un lote de 10 aeronaves (la constante N_AERONAVES).
Es decir, con
1
a1.id = 6;
genera el código por pantalla en la imagen 1, es decir:
1
6     C     1     57
, como en la imagen:
1

COSAS PARA ACLARAR:
· La función
1
cargar()
no se usa.
· Sólo se deben usar las bibliotecas que aparecen en el código, ninguna otra más.
· La plantilla
1
filseSize()
se usa para evaluar si en el archivo "aeronaves.dat" hay contenido; esto es cierto ya que aparece que cada registro equivale a 32 (bytes, bites, no sé en qué formato está, pero se sabe que hay contenido).
· La idea del programa no es extraer la información del código, sino del archivo.
· La carga de las aeronaves no las hace el usuario, ya que si el lote es de 100 aeronaves debe ingresar cada dato por separado. Para resolver esto, hay cosas que las ingresé manualmente, tal como las Horas de Vuelo, etc. La matrícula está declarada como char porque me explicaron que el struct no soporta STRING, así que sólo ingresé manualmente algunas matrículas (10 en total).

¿Pueden decirme qué está fallando?
Por favor, cualquier cosa que no se haya entendido avisar.

Muchas gracias!
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

Problema con archivo binario

Publicado por Emanuel (2 intervenciones) el 16/08/2017 04:57:01
Agrego:

Lo que se hizo fue agregar una nueva aeronave con todos los campos vacíos, excepto el id. Al principio sólo la parte de la línea 223 (el criterio) de la "Aeronave b" por cualquier número, pero el profesor recomendó que es mejor crear una aeronave con el único campo, id, lleno.
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