Lectura Fichero caracter a caracter

Iniciado por P.AGCD, 18 Julio 2011, 18:21 PM

0 Miembros y 1 Visitante están viendo este tema.

P.AGCD

Tengo un problema, mi codigo no lee correctamente el fichero y no se arreglarlo.

Veamos tengo que leer el fichero de esta manera

Equipo1 - Equipo2 : resultado1 resultado2

FICHERO:


Luis y Pepe-Los Supermuseros: 5 0
Sevillanos-Pili y Mili: 2 3
Javier y Lopez-Valencia:4 1
Pili y Mili-Luis y Pepe: 2 3
Los Supermuseros-Javier y Lopez: 0 5


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
# define MAX 80
# define MAX_EQUIPOS 15
# define MAX_PARTIDAS 40

typedef struct  {
   char NombreEquipo [MAX];
   int puntos;
   int numpartidas;
   int numpartidasganadas;
   int numpartidasperdidas;
} Equipo;

typedef struct  {
    Equipo InformacionEquipo [MAX_EQUIPOS];
   int numequipos;
}Lista_Equipos;

typedef struct {
   char Equipo1 [MAX];
   char Equipo2 [MAX];
   int Resultado1;
   int Resultado2;
}Partida ;

typedef struct  {
   Partida InformacionPartida [MAX_PARTIDAS];
   int numpartidas;
}Lista_Partidas;



void LeerArchivoPartida (Lista_Equipos *ListaEquipos, Lista_Partidas *ListaPartidas)

{
   int i=0;
   int p=0;
   int k=0,j=0;
   char caracter;
   
   FILE *archivoPartida;
   
   archivoPartida = fopen ("Resultados.txt", "r");
   
   if (archivoPartida == NULL) {
      printf("NO EXISTE EL FICHERO!\n");
      exit(1);
   }
   
   while (!feof(archivoPartida)) {
      
      caracter = fgetc(archivoPartida);
      while (caracter!='-') {
         ListaPartidas->InformacionPartida.Equipo1[k]=caracter;
         caracter=fgetc(archivoPartida);
         k++;
      if (caracter=='-')
         ListaPartidas->InformacionPartida.Equipo1[k]='\0';
         
      }
      
      while (caracter!=':') {
         ListaPartidas->InformacionPartida.Equipo2[j]=caracter;
         caracter=fgetc(archivoPartida);
         j++;
      
      if (caracter==':')
         ListaPartidas->InformacionPartida.Equipo2[j]='\0';
      }
      puts(ListaPartidas->InformacionPartida.Equipo1);
      printf("\n");
      puts(ListaPartidas->InformacionPartida.Equipo2);
      printf("\n");
      fscanf(archivoPartida, "%d %d", &ListaPartidas->InformacionPartida.Resultado1,&ListaPartidas->InformacionPartida.Resultado2);
      printf("%d %d", ListaPartidas->InformacionPartida.Resultado1,ListaPartidas->InformacionPartida.Resultado2);
      i++;
   }

Ferno

1° Recuerda usar GeSHi para postear código, lo cual facilita la lectura (al menos un poco).
2° A simple vista, te falta leer un caracter entre los dos primeros loops, es decir:

caracter = fgetc(archivoPartida);
     while (caracter!='-') {
        ListaPartidas->InformacionPartida.Equipo1[k]=caracter;
        caracter=fgetc(archivoPartida);
        k++;
     if (caracter=='-')
        ListaPartidas->InformacionPartida.Equipo1[k]='\0';
       
     }

     caracter = fgetc(archivoPartida); //Te falta esto, sino se asigna "-" en la primer posición del segundo equipo.
     
     while (caracter!=':') {
        ListaPartidas->InformacionPartida.Equipo2[j]=caracter;
        caracter=fgetc(archivoPartida);
        j++;
     
     if (caracter==':')
        ListaPartidas->InformacionPartida.Equipo2[j]='\0';
     }


3° Exactamente ¿Cuál es el error?

rir3760

Cita de: P.AGCD en 18 Julio 2011, 18:21 PMTengo un problema, mi codigo no lee correctamente el fichero y no se arreglarlo.
Va a ser difícil ayudarte con tu problema ya que no presentas el código fuente completo de esa función.

Hay algunos nombres que deberían ser mas largos, por ejemplo tienes "MAX", si bien es un máximo no hay forma de saber de que, seria mejor algo como "MAX_LONG_ALGO".

Otros nombres deberían ser mas cortos, por ejemplo en el tipo "Equipo" no es necesario indicar que el campo es "NombreEquipo" ya que eso se saca del contexto, bastaría con solo "nombre".

En cuanto al bucle principal en este no es necesario colocar la condición de escape dentro del bucle interno, eso lo das por sentado al finalizar el bucle.

Esto:
caracter = fgetc (archivoPartida);
while (caracter != '-') {
   ListaPartidas->InformacionPartida[i].Equipo1[k] = caracter;
   caracter = fgetc (archivoPartida);
   k++;
   if (caracter == '-')
      ListaPartidas->InformacionPartida[i].Equipo1[k] = '\0';
     
}

while (caracter != ':') {
   ListaPartidas->InformacionPartida[i].Equipo2[j] = caracter;
   caracter = fgetc (archivoPartida);
   j++;
   
   if (caracter == ':')
      ListaPartidas->InformacionPartida[i].Equipo2[j] = '\0';
}


Lo puedes reducir a:
while ((caracter = fgetc(archivoPartida)) != '-')
   ListaPartidas->InformacionPartida[i].Equipo1[k++] = caracter;
ListaPartidas->InformacionPartida[i].Equipo1[k] = '\0';

while ((caracter = fgetc (archivoPartida)) != ':') {
   ListaPartidas->InformacionPartida[i].Equipo2[j++] = caracter;
ListaPartidas->InformacionPartida[i].Equipo2[j] = '\0';

Se ve muy feo pero eso es a causa de los nombres excesivamente largos, del contexto se deduce que "ListaEquipos" y "ListaPartidas" son listas así que se pueden reducir a solo "equipos" y "partidas" sin afectar la claridad del código fuente.

Por cierto la variable "caracter" (mejor dejarlo como "car" o "ch") debe ser del tipo "int" ya que ese es el tipo de retorno de la función "fgetc".

Algo que también falta es descartar el resto de la linea (al menos el '\n') después de la llamada a fscanf, eso se consigue con:
{
   int ch;
   
   while ((ch = fgetc(archivoPartida)) != EOF && ch != '\n')
      ;
}


Una forma de leer las lineas almacenadas en un archivo y con el formato que indicas es:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LONG_MAX_LINEA  256
#define NOM_ARCHIVO  "Entrada.txt"

struct partido {
   char local[LONG_MAX_LINEA];
   char visitante[LONG_MAX_LINEA];
   int goles_loc;
   int goles_vis;
};

struct partido extraer(char const linea[]);

int main(void)
{
   FILE *entrada;
   char linea[LONG_MAX_LINEA];
   struct partido p;

   if ((entrada = fopen(NOM_ARCHIVO, "r")) == NULL){
      perror(NOM_ARCHIVO);
      return EXIT_FAILURE;
   }

   while (fgets(linea, LONG_MAX_LINEA, entrada) != NULL){
      p = extraer(linea);

      printf("Local: %s\n", p.local);
      printf("Visitante: %s\n", p.visitante);
      printf("Resultado: %d - %d\n", p.goles_loc, p.goles_vis);
   }

   fclose(entrada);

   return EXIT_SUCCESS;
}

struct partido extraer(char const linea[])
{
   struct partido p;
   char *a;
   char *b;

   /* Obtenemos la posicion del caracter '-' */
   a = strchr(linea, '-');
   sprintf(p.local, "%.*s", a - linea, linea);

   /* Obtenemos la posicion del caracter ':' */
   a++;
   b = strchr(a, ':');
   sprintf(p.visitante, "%.*s", b - a,  a);

   /* Los goles los extraemos con sscanf */
   sscanf(++b, "%d %d", &p.goles_loc, &p.goles_vis);

   return p;
}


Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language