[MULTI] Estructura de datos (error imposible)

El fragmento de codigo donde esta implementado el modo de apertura, en el switch me entra en case default pero he imprimido la variable de la que depende el switch y deberia entrar en el case 'I':

Cometido de la funcion
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.
*/


Definicion de la estructura
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;
}


Aqui la funcion de donde viene

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");
  } 
}
Hola.

No me he mirado muy bien el código, per un "posible" fallo (que no lo sé, igual ya lo has tratado tú), es que a los switchs les pasas un dato de tipo char, pero no sé muy bien si tú manualmente lo conviertes en mayúscula/minúscula (siempre es bueno, si lo grabas como 'a', no es lo mismo que 'A', yo siempre les pongo un tolower(); y tirando millas), quizás sea este el fallo...

En uno compruebas si son mayúsculas...y en otro minúsculas...además...según dices...te da bien el valor...¿será este el problema?.

Un saludo.
Hola, he probado la función quitandole las llamadas a funciones que no has puesto y, como era de esperar va bien. Si quieres pon todo el código para compilarlo tal como lo tienes tu.

Saludos.

PD: El código tiene un estilo que me es muy familiar, ¿estudias en la UCA?
Consegui solucionarlo (una pamplina), pero ahora tengo otro fallo :S (esta marcado con muchas !!!)

A que se puede deber? el fseek no lo manejo muy bien

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(&reg,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(&reg,sizeof(reg),1,fsecind->fichero);
  }
  fsecind->posact = i+1;


pd: si soy de la uca :P
Tienes el include sys/types.h. Creo q la constante SEEK_END esta definida en esa cabecera.
4 respuestas