[RESUELTO]Comprobar formato de un fichero de texto

Iniciado por atioira, 9 Mayo 2017, 19:23 PM

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

atioira

Hola, intento hacer un programa que que abra un fichero si no existe lo cree y si no compruebe que tiene el formato correcto que seria:
:1:maria:
:2:marta:
:3:jorge:
si esta mal devuelve error y si esta bien muestra por pantalla lo que hay en el fichero.
El problema es que no funciona y no se  muy bien porque, tenia hecho un programa que pedia que se introdujeran los datos y hacia lo mismo y lo modifique para que lo hiciera con ficheros pero no funciona
Gracias por la ayuda

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

// Un entero no negativo de 32 bits ocupa como máximo 10 caracteres
#define MAX_LON_NUMERO 2
// Sólo admitimos nombres de hasta 255 caracteres
#define MAX_LON_NOMBRE 50
// La línea de entrada debe admitir los 10 del entero + 3 ':' +
// los 255 del nombre + los 3 ':' + 1 para el '\n'
#define MAX_LON_LINEA MAX_LON_NUMERO+3+MAX_LON_NOMBRE+1

int main () {

 // en todas las cadenas reservamos espacio para el '\0'
 char linea[MAX_LON_LINEA+1];    // La línea tecleado por el usuario
 char num[MAX_LON_NUMERO+1];     // El número en formato de cadena
 int numero;                     // El número pasado a entero
 char nombre[MAX_LON_NOMBRE+1];  // El nombre leído
 int correcto;                   // Control de errores
 int i, j;                       // Índices
 
 FILE *lectores;
 lectores=fopen("lectores.txt","r");
 if(lectores==NULL){
   printf("no existe el fichero\n");
   lectores=fopen("lectores.txt","w");
   return 0;
 }
 else{  
   
   do {
     correcto = 1;
     fgets (linea, sizeof(linea), lectores);
     
     // Si el último carácter leído no es un '\n', es que el usuario ha
     // tecleado una línea demasiado larga => entrada no correcta
     if (linea[strlen(linea)-1] != '\n') {
correcto = 0;
printf("demasiado larga\n");
// Extraemos (y descartamos) el resto de la línea
while (fgetc(lectores) != '\n') ;
     }
     // El primer caracter y el anterior al '\n' deben ser ':'
     // Si no  => entrada no correcta
     else if ((linea[0] != ':') || (linea[strlen(linea)-2] != ':')){
correcto = 0;
printf("no : no 1 e no ultimo\n");
     }
     else {
// Si lo anterior se cumple, ponemos un '\0' en lugar del ':' final
linea[strlen(linea)-2] = '\0';
// Extraemos los dígitos que haya después del ':' inicial
// Es decir, a partir del 2º caracter (índice 1)
i = 1;
j = 0;
while ((isdigit(linea[i])) && (j < MAX_LON_NUMERO)) {
 num[j++] = linea[i++];
}
// Si hemos extraído 0 dígitos => entrada no correcta
if (j == 0){
 correcto = 0;
 printf("non eran digitos\n");
}
else {
 // Acabamos la cadena del número con un '\0'
 num[j] = '\0';
 // Lo convertimos a entero
 numero = atoi(num);
 // Si el siguiente carácter no es un ':' => entrada no correcta
 if (linea[i++] != ':'){
   correcto = 0;
   printf("non hai : no medio\n");
 }
 else {
   // Extraemos los caracteres del nombre
   j = 0;
   while ((i < strlen(linea)) && (j < MAX_LON_NOMBRE)) {
     // No puede haber ningún otro ':'
     if (linea[i] != ':') {
nombre[j++] = linea[i++];
     }
     // Si hay algún ':' más => dejamos de extraer
     else
break;  // Sale de este while interior
   }
   // Si hemos extraído 0 caracteres o no hemos terminado de extraer el
   // nombre (sea porque había más caracteres de los que caben en el
   // nombre o porque contenía algún ':') => entrada no correcta
   if ((j == 0) || (i < strlen(linea))){
     correcto = 0;
     printf("habia : no nombre ou nombre muy largo\n");
   }
   // Acabamos la cadena del nombre con un '\0'
   else nombre[j] = '\0';
 }
}
     }
     // Si la entrada no es correcta, avisamos al usuario
     if (!correcto)
fprintf (stdout, "\nLinea mal formada en el fichero (lectores.txt).\n");
     
     // Mientras no tengamos una entrada correcta, seguimos
   } while (!correcto);
   
   //Mostramos los datos extraídos
   fprintf(stdout,"\nEl numero es: %d. Y el nombre es: %s\n\n", numero, nombre);
 }
 
 return 0;
}

MAFUS

¿Qué tal así?

Después del fgets(...) que has llegado al final del fichero con if(feof(lectores)) return 0;

Por cierto. Podrías decirme la utilidad de crear un archivo "vacío" si el archivo no existe?

atioira

No entiendo porque compruebas que llego al final del fichero ahi?
de todas formas si lo pruebo con un formato correcto solo me muestra la primera linea, es decir, solo me comprueba la primera comohago para que lo hago con todo el fichero?
Lo de crealo si no existe es porque despues de comprobar si el formato es correcto tengo que añadir mas lineas y si no existe el fichero crearlo para empezar a añadir.
Gracias.

MAFUS

#3
Eso es por si llegas al final del archivo después de una lectura y no sigas con el bucle sin nada que computar.


Sólo te da un resultado porqué tienes el fprintf que te muestra los resultados fuera del bucle principal, con lo que solo leerá una vez un formato correcto. ¿Que hacer?

1. Antes de entrar en el bucle principal haz una lectura con fgets.
2. Cambia todo el formato de bucle do - while por
while(!feof(lectores))
3. Antes de terminar el bucle inserta dentro el fprintf para visualizar los datos correctos.
4. Justo antes de terminar el bucle y después del fprintf del punto #3 vuelve a realizar una lectura con fscanf.

Los cambios:
       lectores=fopen("lectores.txt","w");
       return 0;
   }
   else{
       fgets (linea, sizeof(linea), lectores);
       while(!feof(lectores)) {
           correcto = 1;
           // Si el último carácter leído no es un '\n', es que el usuario ha
           // tecleado una lí­nea demasiado larga => entrada no correcta


// Si la entrada no es correcta, avisamos al usuario
           if (!correcto)
               fprintf (stdout, "\nLinea mal formada en el fichero (lectores.txt).\n");
           
           else {
               // Si lo es Mostramos los datos extraí­dos
               fprintf(stdout,"\nEl numero es: %d. Y el nombre es: %s\n\n", numero, nombre);
               fflush(stdout);
           }
           
           fgets (linea, sizeof(linea), lectores);
       }
   }
 
   return 0;

atioira

ah vale claro por eso me me hacia un bucle infinito, claro no me di cuenta que hacia el printf fuera.
Porque al final vuelvo a leer con fscan o fgets?
muchas gracias por resolver mis dudas.

MAFUS

Lo haces al final para capturar la nueva línea; entonces el bucle se repite y si no has llegado al final del archivo volverá a repetirse.

atioira