Dev - C++ - Cosa absurda (C - Archivos)

 
Vista:

Cosa absurda (C - Archivos)

Publicado por argio (1 intervención) el 25/06/2010 02:09:32
Bueno, como explicar ésto, tengo una base de datos de unos 54k, estructurada así:
struct {
int ART ;
char DESC[20] ;
int STOCK ;
char PROVE[15];
float PRECIO ;
} ;

tengo que sacar cual es el proveedor con más variedad de artículos(diferentes, el stock y demás ni se tiene en cuenta, lo que se tiene en cuenta es cuantas veces aparece el proveedor en la bd)

bueno, lo ridículo es que, con un código en la cual la lógica es absolutamente correcta, me muestra erróneamente el resultado(no muestra el proveedor, y pone cualquier numero en la cantidad de veces que aparece), pero, con el MISMO codigo, y , un paso de más, lo muestra correctamente

lo analizé y lo analizé y sigo afirmando que ese paso está de más, pero si se lo saco, lo muestra erróneamente.

Código con el que anda:
(el paso de más es que copia el nombre del proveedor en el string auxiliar "pro", pero, si se lo quito, deja de mostrar el resultado correctamente.)

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

struct PRODUCTO{
int ART;
char DESC[20];
int STOCK;
char PROVE[15];
float PRECIO;
};

void main(){
FILE *fp;
FILE * aux;
int can , canMay ;
char pro [15] , proMay [15];
struct PRODUCTO pr1 , pr2;

if((fp=fopen("BD","r+b"))==NULL)
{
printf("errorfp");
exit(1);
}
if((aux=fopen("BD","rb"))==NULL)
{
printf("erroraux");
exit(1);
}

canMay = 0;
fread(&pr1,sizeof(pr1),1,fp);
while(!feof(fp))
{
can = 0;
strcpy(pro , pr1.PROVE); //esto es parte del paso de mas
fread(&pr2,sizeof(pr2),1,aux);
while(!(feof(aux)))
{
if(strcmp (pro , pr2.PROVE)==0)//esto sería lo mismo que compararlo contra pr1.PROVE
{
can++;
strcpy( pro , pr1.PROVE);//de más
}
fread(&pr2,sizeof(pr2),1,aux);
}
rewind(aux);
if(canMay < can)
{
canMay = can;
strcpy(proMay , pro);
}
fread(&pr1,sizeof(pr1),1,fp);
}
fclose(fp);
fclose(aux);
printf("\n\nMAYOR PROVEEDOR %s" , proMay);
printf("\nPRODUCTOS %d\n\n" , canMay);
getchar();
printf("\n\nFIN DEL PROGRAMA\n");
getchar();
}


Bueno, si a ese codigo, le quitas la parte de strcpy(pro , pr1.PROVE), y, despues en :
if(strcmp (pro , pr2.PROVE)==0), a pro lo reemplazas por pr1.prove, y , en los otros 2 reemplazas pro por pr1.prove también, el programa no muestra el resultado correctamente

es totalmente absurdo, alguien que me pueda dar una mano, espero que se haya entendido, más o menos.
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

RE:Cosa absurda (C - Archivos)

Publicado por argio (1 intervención) el 25/06/2010 02:48:01
La lógica del programa es, abrir 2 veces la BD, en 2 stream distintos (FP y FP2) y cada vez que leo un registro en FP, realizo un recorrido del mismo archivo pero en FP2, para ver cuantas veces aparece en la base de datos.
Si no se entiende avisen

Les adjunto la base de datos:
http://www.mediafire.com/?mtttzdnyxti
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

RE:Cosa absurda (C - Archivos)

Publicado por Capitan Kirk (48 intervenciones) el 25/06/2010 09:08:27
Una pequeña sugerencia:

Dado que el archivo lo estás abriendo como binario y, básicamente, en estos archivos indicas cuántos bytes quieres leer o escribir cada vez, será más cómodo escribir al principio del archivo un simple número entero en el que indiques el número de registros que contiene el archivo. Es decir, lo primero que lees es el número de registros, y ya sabes cuántos tienes, sin necesidad de preocuparte por la marca de final de archivo. Lógicamente, este número lo actualizas cada vez que añadas o elimines registros.

Cuando lees un archivo, al leer el último elemento, aún no se ha leído la marca de final de archivo. Esta señal se activa cuando intentas leer después del último elemento, y el contenido de lo leído está indeterninado, aunque por mi experiencia es lo mismo que lo último que leyó correctamente. Por ello, cuando leas un archivo, comprueba si se ha alcanzado el final de fichero tras cada lectura (aunque estés en un bucle while (!feof(fp)) ) y antes de tratar esa lectura. Ten también en cuenta que, en ficheros secuenciales (de texto) la marca de fin de archivo es el código ASCII 26, etiquetado como Ctrl-Z, pero esto no es aplicable a ficheros binarios, dado que este código puede formar parte de cualquier cosa. Por ello es más cómodo emplear el sistema que te he indicado arriba (alguno lo puede considerar chapucero, pero es eficaz).

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