› Foros › Multiplataforma › Desarrollo
Precondiciones: El parámetro nomfich es un puntero a una
cadena de caracteres que contiene el nombre de un fichero
externo secuencial indexado.
El parámetro modo es un carácter que indica cómo se debe
abrir el fichero. Los modos de apertura son los siguientes:
‘I’ (inicio): El fichero se crea nuevo para lectura y escritura.
‘C’ (consulta): El fichero se abre sólo para lectura.
'A' (actualización): El fichero se abre para lectura y escritura.
Postcondiciones: Abre el fichero externo secuencial indexado
nomfich y devuelve un fichero interno secuencial indexado al
que queda enlazado. Si el modo de apertura es ’I’, crea un
fichero vacío. Si previamente existía, primero lo borra. La po-
sición activa para la primera lectura secuencial queda esta-
blecida en el primer persona (por orden de clave) del fichero.
Si el fichero está vacío, la posición activa es fin de fichero.
*/
typedef int tclave; /* Por ejemplo */
#ifndef _CARTA_
#define _CARTA_
typedef struct {
tclave clave;
char nombre[10];
int dano, energia;
char turno; // a ataque, d defensa, b ambos
} carta;
#endif
#ifndef _FICHDIR_
#define _FICHDIR_
typedef struct {
tclave clave;
long pos;
} tipoIndice;
typedef struct {
FILE *fichero;
tipoIndice *indice;
char *nombre;
int tama;
char modoAp;
long posact;
} tipoFichSecInd;
typedef tipoFichSecInd *FichSecInd;
FichSecInd AbrirFichSecIndCarta(const char *nomfich, char modo)
{
FichSecInd fsecind;
fsecind = (tipoFichSecInd *) malloc(sizeof(tipoFichSecInd));
if (fsecind == NULL)
ERROR("AbrirFichSecInd: Memoria insuficiente");
if ((modo == 'C' || modo == 'A') && !ExisteFichSecInd(nomfich))
ERROR("AbrirFichSecInd: Fichero inexistente. " "Modo incompatible");
printf("%c", modo);
switch (modo)
{
case 'I': /*Crear vacío para lectura/escritura*/
fsecind->fichero=fopen(nomfich,"wb+");
break;
case 'C': /* Abrir para lectura */
fsecind->fichero=fopen(nomfich,"rb");
break;
case 'A': /* Abrir para lectura/escritura */
fsecind->fichero=fopen(nomfich,"rb+");
break;
default: ERROR("AbrirFichSecInd: " "Modo de apertura incorrecto");
}
fsecind->nombre = (char *) malloc(strlen(nomfich)*sizeof(char));
if (fsecind->nombre == NULL)
ERROR("AbrirFichSecInd: Memoria insuficiente");
strcpy(fsecind->nombre, nomfich);
fsecind->modoAp = modo;
if (modo == 'I') {
fsecind->indice = NULL;
fsecind->tama = 0;
}
else /* modo ’C’ o ’A’ */
IndexarCarta(fsecind);
fsecind->posact = 0;
return fsecind;
}
char NomP[] = "personajes", NomC[] = "cartas";
FichSecInd FicheroDatos;
static void IniciaCreacion (char tipo)
{
switch (tipo)
{
case 'c':
//strcpy (NomFichero, "cartas");
FicheroDatos = AbrirFichSecIndCarta(NomC, 'I');
comprobacion();
CerrarFichSecIndCarta (FicheroDatos);
break;
case 'p':
//strcpy (NomFichero, "personajes");
FicheroDatos = AbrirFichSecInd(NomP, 'I');
comprobacion();
CerrarFichSecInd (FicheroDatos);
break;
default:
ERROR("Tipo incorrecto");
}
}
void EscribirFichSecIndCarta (FichSecInd fsecind, carta reg)
{
int i, j, tama, encontrado;
if (fsecind->modoAp == 'C')
ERROR("EscribirFichSecInd: Modo incompatible");
i = 0; encontrado = 0;
while (i < fsecind->tama && !encontrado)
if (fsecind->indice[i].clave < reg.clave)
i++;
else
encontrado = 1;
if (!encontrado || fsecind->indice[i].clave > reg.clave) {
/* Insertar clave en índice y escribir carta en fin de fichero */
fsecind->indice = (tipoIndice *) realloc(fsecind->indice, (fsecind->tama+1)*sizeof(tipoIndice));
if (fsecind->indice == NULL)
ERROR("EscribirFichSecInd: " "Memoria insuficiente");
for (j = fsecind->tama; j > i; j--)
fsecind->indice[j] = fsecind->indice[j-1];
fsecind->indice[i].clave = reg.clave;printf("todo ok");getchar();
fseek(fsecind->fichero, 0, SEEK_END);//¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡fallo!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
tama = ftell(fsecind->fichero) / sizeof(reg); printf("todo ok");getchar();
fsecind->indice[i].pos = tama;
fwrite(®,sizeof(reg),1,fsecind->fichero);
fsecind->tama++;
}
else { /* ya existe la clave, sobreescribir */
fseek(fsecind->fichero,
fsecind->indice[i].pos*sizeof(reg),
SEEK_SET);
fwrite(®,sizeof(reg),1,fsecind->fichero);
}
fsecind->posact = i+1;