Buenas a todos.
Les cuento, tengo un archivo que almacena registros de longitud fija.
Mi archivo tiene un registro encabezado que almacena info sobre:
* El número de registros de datos del archivo
* La longitud de los registros de datos
+----------------------+
+ 5 + recordLength +
+----------------------+
+ NR+ MAS CAMPOS +
+----------------------+
+ 1 + .... data ........+
+ 2 + .... data ........+
+ 3 + .... data ........+
+ 4 + .... data ........+
+ 5 + .... data ........+
typedef struct Record{
char firstName[20];
char lastName[20];
char nationality[20];
char DNI[9];
int age;
int recordNumber;
}Record;
typedef struct Header{
int numberOfRecords;
int recordLength;
}Header;
Lo que hago al crear un archivo es inicializar los campos del registro encabezado y grabarlo:
void createFile(char* nameFile)
{
FILE* fd;
Header buffer;
buffer.numberOfRecords = 0;
buffer.recordLength = sizeof(Record);
fd
= fopen(nameFile
,"wt"); fwrite(&buffer
,1,sizeof(Header
),fd
); // Compruebo el valor inicial que se grabo en numberOfRecords y me da 0, es correcto
printf("Valor: %d",buffer.
numberOfRecords); }
Como se habrán dado cuenta cada registro Record tiene un campo el cual indica que numero de registro es.
Lo que hago para asignarle el valor al campo recordNumber, leo el encabezado(el numero de registros) y a ese le sumo uno, El cual seria el numero de registros actuales.
El problema es en la función para agregar un registro al archivo:
void addRecord(FILE** fd,Record data)
{
struct Header buffer;
fread(&buffer
, 1,sizeof(Header
) , *fd
); buffer.numberOfRecords++;
printf("Valor?: %d\n",buffer.
numberOfRecords);
data.recordNumber = buffer.numberOfRecords;
// Compruebo el contenido del registro recibido.
// Pero el campo NR no se actualizo... Sale un numero extrano
printf("% 10d% 12s% 12s% 12s% 12s% 12d\n", data.recordNumber,
data.firstName,
data.lastName,
data.nationality,
data.DNI,
data.age
);
printf("\n\t\t\t Press enter key to continue"); fgetchar();
//
// int pos = (data.recordNumber-1) * buffer.recordLength + sizeof(Header);
// fseek(*fd,2,0);
// fwrite(&data,1, buffer.recordLength, *fd);
// fseek(*fd,0,0);
// fwrite(&buffer, 1,sizeof(Header), *fd);
}
Mi problema es que cuando creo el archivo e inicializo el encabezado (numero de registros igual 0) funciona perfecto, pero cuando voy a leer luego el encabezado en ese campo esta un valor
"extraño".
Aqui les dejo mi programa:
#ifdef __linux__
#define CLEAN "CLEAR"
#endif
#ifdef __MINGW32__
#define CLEAN "CLS"
#endif
#ifdef __MINGW64__
#define CLEAN "CLS"
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define TAM_CADENA 20
typedef struct Record
{
char firstName[20];
char lastName[20];
char nationality[20];
char DNI[9];
int age;
int recordNumber;
}Record;
typedef struct Header
{
int numberOfRecords;
int recordLength;
}Header;
void readLine(char cadena[], int tam);
int readInt();
void addRecord(FILE** fd,Record data);
int getRecordNumber(FILE** fd);
void createFile(char* nameFile);
int subMenu(char* fileName);
void menu();
int main(int argc, char *argv[])
{
menu();
return 0;
}
void menu()
{
int op = 0;
char nameFile[TAM_CADENA];
do{
printf("\n\t\t# | > _ _ _ _ _ _ __ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ < | #"); printf("\n\t\t# | > [x1] Create File < | #"); printf("\n\t\t# | > [x2] Open file for... < | #"); printf("\n\t\t# | > [x3] Dump File < | #"); printf("\n\t\t# | > [x4] Search Record < | #"); printf("\n\t\t# | > [x5] Filter by Nationality < | #"); printf("\n\t\t# | > [x6] Exit < | #"); printf("\n\t\t# | >_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ < | #"); printf("\n\t\t\t Enter option: "); op = readInt();
switch(op){
case 1: printf("\n\t\t\t Enter the file name: "); readLine(nameFile,TAM_CADENA);
createFile(nameFile);
printf("\n\t\t\t Press enter key to continue"); fgetchar();
break;
case 2: printf("\n\t\t\t Enter the file name: "); readLine(nameFile,TAM_CADENA);
subMenu(nameFile);
break;
case 3: printf("\n\t\t\t Enter the file name: "); readLine(nameFile,TAM_CADENA);
seeAll(nameFile);
printf("\n\t\t\t Press enter key to continue"); fgetchar();
break;
case 4: printf("\n\t\t\t Press enter key to continue"); fgetchar();
break;
case 5: printf("\n\t\t\t Press enter key to continue"); fgetchar();
break;
case 6: printf("\n\t\t\t Good bye :)"); printf("\n\t\t\t Press enter key to continue"); fgetchar();
break;
default:printf("\n\t\t\t [msgError]: Invalid option."); }
}while(op!=6);
}
int subMenu(char* fileName)
{
FILE* fd;
if( (fd
=fopen(fileName
,"a+t")) == NULL
) {
printf("\nCould not open the file."); return -1;
}
else
{
int op = 0, R;
Record buffer;
do{
R = getRecordNumber(&fd);
printf("\n\t\t# | >>_ _ _++=[-> File: %s R: %d<-]=++_ _ _ << | #", fileName
,R
); printf("\n\t\t# | >_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ < | #"); printf("\n\t\t# | > [x1] Add new records. < | #"); printf("\n\t\t# | > [x2] Change record < | #"); printf("\n\t\t# | > [x3] Close file < | #"); printf("\n\t\t# | >_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ < | #"); printf("\n\t\t\t Enter option: "); op = readInt();
switch(op){
case 1: printf("\n\t\t\t Enter First Name: "); readLine(&buffer.firstName,TAM_CADENA);
printf("\n\t\t\t Enter Last Name: "); readLine(buffer.lastName,TAM_CADENA);
printf("\n\t\t\t Enter Nationality: "); readLine(buffer.nationality,TAM_CADENA);
printf("\n\t\t\t Enter DNI: "); readLine(buffer.DNI,9);
printf("\n\t\t\t Enter Age: "); buffer.age = readInt();
addRecord(&fd, buffer);
break;
case 2: printf("\n\t\t\t Press enter key to continue"); fgetchar();
break;
printf("\n\t\t\t File closed."); break;
default:printf("\n\t\t\t [msgError]: Invalid option."); }
}while(op!=3);
}
return 0;
}
void createFile(char* nameFile)
{
FILE* fd;
struct Header buffer;
buffer.numberOfRecords = 0;
buffer.recordLength = sizeof(Record);
fd
= fopen(nameFile
,"wt"); fwrite(&buffer
,1,sizeof(Header
),fd
); // Compruebo el valor inicial que se grabo en numberOfRecords
// 0 es correcto
printf("Valor de nr: %d",buffer.
numberOfRecords); }
int getRecordNumber(FILE** fd)
{
struct Header buffer;
fread(&buffer
, 1, sizeof(Header
),*fd
); return buffer.numberOfRecords;
}
void addRecord(FILE** fd,Record data)
{
struct Header buffer;
fread(&buffer
, 1,sizeof(Header
) , *fd
); buffer.numberOfRecords++;
printf("Valor de nr: %d\n",buffer.
numberOfRecords);
data.recordNumber = buffer.numberOfRecords;
// Compruebo el contenido del registro recibido.
// Pero el campo NR no se actualizo... Sale un numero extraño
printf("% 10d% 12s% 12s% 12s% 12s% 12d\n", data.recordNumber,
data.firstName,
data.lastName,
data.nationality,
data.DNI,
data.age
);
printf("\n\t\t\t Press enter key to continue"); fgetchar();
//
// int pos = (data.recordNumber-1) * buffer.recordLength + sizeof(Header);
// fseek(*fd,2,0);
// fwrite(&data,1, buffer.recordLength, *fd);
// fseek(*fd,0,0);
// fwrite(&buffer, 1,sizeof(Header), *fd);
}
int seeAll(char* nameFile)
{
FILE* fd;
if( (fd
=fopen(nameFile
,"rt")) == NULL
) {
printf("\nCould not open the file."); return -1;
}
else
{
struct Record buffer;
struct Header header;
fread(&header
,1,sizeof(Header
), fd
); while(fread(&buffer
,1,header.
recordLength,fd
) == 1) {
printf("% 10d% 12s% 12s% 12s% 12s% 12d\n", buffer.recordNumber,
buffer.firstName,
buffer.lastName,
buffer.nationality,
buffer.DNI,
buffer.age
);
}
}
return 0;
}
int readInt()
{
char buf[BUFSIZ];
char *p;
long int i;
if (fgets(buf
, sizeof(buf
), stdin
) != NULL
) {
if (buf[0] != '\n' && (*p == '\n' || *p == '\0'))
return i;
}
}
void readLine(char cadena[], int tam)
{
char c;
if (cadena
[strlen(cadena
)-1] == '\n') cadena
[strlen(cadena
)-1] = '\0'; else
{
cadena[tam-1] = '\0';
}
}
Gracias de antemano.