Almacenar datos de un fichero en una estructura

Iniciado por moralescmj, 26 Enero 2014, 00:15 AM

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

moralescmj

Hola a todos, acabo de empezar este año en ingeniería a tocar el tema de la programación en C y tengo una duda sobre un ejercicio que me mandaron hacer.
La cosa es que tengo que leer unos datos de un fichero, que simplemente se dividen en 3 columnas por lo que lo leo con fscanf, y tengo que almacenar esos datos en un struct. Me he estado informando por este foro y lo que voy encontrando es que tengo que hacer uso de la memoria dinámica (el malloc o algo así), pero nuestro profesor nos dijo que era algo mucho mas fácil que eso.
Llevo varios días probando cosas pero  no consigo nada...
Creo que tengo que hacer uso de los arrays con los struct, pero es un tema que hemos tocado muy poco en clase y si el profesor nos pide esto de repente, pues claro... Como si no supieramos nada...
Agradeciería vuestra ayuda.
Muchas gracias:)

rir3760

Cita de: moralescmj en 26 Enero 2014, 00:15 AMtengo que leer unos datos de un fichero, que simplemente se dividen en 3 columnas por lo que lo leo con fscanf, y tengo que almacenar esos datos en un struct. Me he estado informando por este foro y lo que voy encontrando es que tengo que hacer uso de la memoria dinámica (el malloc o algo así), pero nuestro profesor nos dijo que era algo mucho mas fácil que eso.
Creo que tengo que hacer uso de los arrays con los struct
Como ya te sugirió tu profesor si hay un limite arbitrario en el numero de registros (máximo N registros) solo tienes que declarar un array para almacenar esa cantidad.

Cita de: moralescmj en 26 Enero 2014, 00:15 AMpero es un tema que hemos tocado muy poco en clase y si el profesor nos pide esto de repente, pues claro... Como si no supieramos nada...
Presenta los avances que llevas del programa e indica en que partes tienes dificultades, a partir de ahí ya podemos ayudarte.

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

moralescmj

#2
Mira, el programa trata de "simular" una caja registradora a partir de la cual, buscamos en un fichero llamado "productos.txt" el código, nombre y precio del producto. En pantalla nos pedirá que le pongamos el codigo del producto que queramos, y el programa nos preguntará además las unidades. En el momento que querramos finalizar y generar un ticket, pulsaremos la tecla 0. Este es el programa hecho de esta forma, y lo que nos piden es modificarlo para que guarde en memoria los productos leídos en el archivo "productos.txt".

Código:
#include <stdio.h>
#include <string.h>
#include <time.h>
#define IVA  0.08




//Función para comprobar si hemos llegado al final de un archivo
int fin_f(FILE *f) {
 int c = fgetc(f);
 ungetc(c, f);
 return (c == EOF);
}

void crearFichero(int numTicket, char nomArch[50]){
   FILE *NOM[50];
   
NOM[numTicket] = fopen(nomArch,"w");
fclose(NOM[numTicket]);

}
//Cabecera de los ticket
void cabecera_ticket(int numTicket, char nomArch[50]){  
FILE *NOM[numTicket];
NOM[numTicket] = fopen(nomArch , "a");

time_t tiempo = time(0); //Función para imprimir la fecha y la hora
    struct tm *tlocal = localtime(&tiempo);
    char output[128];
    strftime(output,128,"%d/%m/%y %H:%M:%S",tlocal);

   
if(NOM[numTicket] == NULL){
printf("Error al abrir el fichero.");
}else{
fprintf(NOM[numTicket], "Ticket nº %d\t %s\n\n",
numTicket, output);
}
fclose(NOM[numTicket]);
}

//Escribe el producto seleccionado en pantalla
void escribir_producto(int existe, char codigoLeidoTeclado[],
  char nombre[],  double *precio){

if (existe==1){
printf("%s %s %0.2lf \n", codigoLeidoTeclado, nombre, *precio);
}else{
printf("No existe un codigo con ese producto \n");
}
}

//Buscar productos en el fichero
int buscar_producto(char codigoLeidoTeclado[],
char nombre[],  double *precio) {
FILE * f1;
int encontrado = 0;
int existe;
char codigoLeidoFichero[100];
f1 = fopen("productos.txt", "r");

if(f1 == NULL){
printf("Error al abrir el fichero.");
}
else{
while(!fin_f(f1) && encontrado == 0){
fscanf(f1, "%s %s %lf", codigoLeidoFichero, nombre, precio);

if(strcmp(codigoLeidoFichero, codigoLeidoTeclado) == 0) {
encontrado = 1;
existe=1;
}
else{
encontrado=0;
existe=0;
}
}
}
fclose (f1);

return(existe);
}

//Calculamos el valor de todos los productos del mismo tipo
double calcular_precio_total(int unidades,double *precio){
double precio_final;
precio_final=(*precio)*(unidades);
return precio_final;
}

//Procedimiento para escribir el ticket
void generar_linea(char codigoLeidoFichero[],char nombre[],
  int unidades, double *precio,
  int numTicket, char nomArch[50]){
FILE * NOM[numTicket];

NOM[numTicket] = fopen(nomArch, "a");
double valor_final;

if(NOM[numTicket] == NULL){
printf("Error al abrir el fichero.");
}else{

//calculamos el precio total de los productos del mismo tipo
valor_final=calcular_precio_total(unidades,precio);

fprintf(NOM[numTicket], "%s\t%-10s%3d\t%0.2lf\t%6.2lf\tEur\n",
codigoLeidoFichero, nombre, unidades,
*precio, valor_final);

}
fclose(NOM[numTicket]);
}


double totalFinal (int unidades, double *valor_total, double *precio){
double valor_final;

valor_final = calcular_precio_total(unidades,precio);
*valor_total = *valor_total + valor_final;
return *valor_total;
}

void finTicket (double *valor_total, int numTicket, char nomArch[50]){
double precio_iva;

precio_iva = *valor_total * IVA;
*valor_total = *valor_total + precio_iva;

FILE * NOM[numTicket];

NOM[numTicket] = fopen(nomArch, "a");

if(NOM[numTicket] == NULL){
printf("Error al abrir el fichero.");
}
else{
fprintf(NOM[numTicket], "\n");

fprintf(NOM[numTicket], "%*s\t%6s\t%6.2lf\tEur\n", 21,
"8%", "IVA" ,precio_iva);

fprintf(NOM[numTicket], "%*s\t%6.2lf\tEur\t",30,
"TOTAL", *valor_total);

}
fclose(NOM[numTicket]);
}


//Programa principal
int main (void){
double valor_total;
char codigoLeidoTeclado[100];
char nombre[100];
char nomArch[50];
int existe = 0;
int unidades = 0;

double precio;
int numTicket = 1;



while(1){
sprintf(nomArch,"ticket%d.txt", numTicket);
printf("Codigo de producto (0 - finalizar compra): ");
scanf("%s", codigoLeidoTeclado);
crearFichero(numTicket, nomArch);
cabecera_ticket(numTicket, nomArch);

while(strcmp(codigoLeidoTeclado, "0") == 1){


// Función que lea datos de productos del fichero
buscar_producto(codigoLeidoTeclado, nombre, &precio);

existe = buscar_producto(codigoLeidoTeclado, nombre, &precio);

//Procedimiento para escribir los productos en pantalla
escribir_producto(existe,codigoLeidoTeclado,nombre,&precio);

//Si existe el producto pediremos el numero de unidades
if (existe==1) {  
printf("Unidades: ");
scanf("%d", &unidades);

//Función que escribe  los productos en el ticket
generar_linea(codigoLeidoTeclado, nombre,  unidades,
 &precio, numTicket, nomArch);
 
totalFinal (unidades, &valor_total, &precio);
}
printf("Codigo de producto (0 - finalizar compra): ");
scanf("%s", codigoLeidoTeclado);
}
finTicket (&valor_total,numTicket, nomArch);

printf("Generado ticket %d \n", numTicket);

numTicket++;
valor_total = 0;
}
}


Hasta aquí el programa funciona perfectamente (sé que se puede mejorar), pero ahora he intentado introducirle un poco el tema de los struct y arrays, y de momento me compila y ejecuta, pero en ejecución me sale lo de "El programa dejó de funcionar" de windows.
Este sería el "prototipo que tengo del nuevo código:
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <math.h>
#define IVA  0.08
#define N 200
#define MAX_LONG 100




//Función para comprobar si hemos llegado al final de un archivo
int fin_f(FILE *f) {
 int c = fgetc(f);
 ungetc(c, f);
 return (c == EOF);
}
struct productos{
char codigoLeidoFichero[MAX_LONG];
char nombre[MAX_LONG];
double precio;
};

void crearFichero(int numTicket, char nomArch[50]){
   FILE *NOM[50];
   
NOM[numTicket] = fopen(nomArch,"w");
fclose(NOM[numTicket]);

}
//Cabecera de los ticket
void cabecera_ticket(int numTicket, char nomArch[50]){  
FILE *NOM[numTicket];
NOM[numTicket] = fopen(nomArch , "a");

time_t tiempo = time(0); //Función para imprimir la fecha y la hora
    struct tm *tlocal = localtime(&tiempo);
    char output[128];
    strftime(output,128,"%d/%m/%y %H:%M:%S",tlocal);

   
if(NOM[numTicket] == NULL){
printf("Error al abrir el fichero.");
}else{
fprintf(NOM[numTicket], "Ticket nº %d\t %s\n\n", numTicket,
output);
}
fclose(NOM[numTicket]);
}

//Escribe el producto seleccionado en pantalla
void escribir_producto(struct productos *prod, char codigoLeidoTeclado[MAX_LONG],int n)
{
printf("%s %s %0.2lf \n", prod[n].codigoLeidoFichero, prod[n].nombre, prod[n].precio);
}

//Buscar productos en el fichero
int buscar_producto(struct productos *prod,char codigoLeidoTeclado[MAX_LONG],int *n)
{
FILE * f1;
int i;
int num_coincide=0;
f1 = fopen("productos.txt", "r");
if(f1 == NULL)
{
printf("Error al abrir el fichero.");
}
else
{
i=0;
while(!fin_f(f1))
{
fscanf(f1, "%s %s %lf", prod[i].codigoLeidoFichero,
prod[i].nombre, &prod[i].precio);
i++;
}

for (num_coincide=0;num_coincide<=i; num_coincide++)
{
fscanf(f1, "%s %s %lf", prod[num_coincide].codigoLeidoFichero,
prod[num_coincide].nombre, &prod[num_coincide].precio);
if (strcmp(prod[num_coincide].codigoLeidoFichero, codigoLeidoTeclado)==0)
{
*n=num_coincide;
break;
}

}
}
fclose (f1);

return i;
}

//Calculamos el valor de todos los productos del mismo tipo
double calcular_precio_total(struct productos *prod,int unidades){

double precio_final;
precio_final=(prod[N].precio)*(unidades);
return precio_final;
}

//Procedimiento para escribir el ticket
void generar_linea(struct productos *prod, char codigoLeidoFichero[],
  int unidades,
  int numTicket, char nomArch[50]){
FILE * NOM[numTicket];

NOM[numTicket] = fopen(nomArch, "a");
double valor_final;

if(NOM[numTicket] == NULL){
printf("Error al abrir el fichero.");
}else{
//calculamos el precio total de los productos del mismo tipo
valor_final=calcular_precio_total(prod,unidades);

fprintf(NOM[numTicket], "%s\t%-10s%3d\t%0.2lf\t%6.2lf\tEur\n",
prod[N].codigoLeidoFichero, prod[N].nombre, unidades,
prod[N].precio, valor_final);

}
fclose(NOM[numTicket]);
}


double totalFinal (struct productos *prod,int unidades, double *valor_total)
{
double valor_final;
valor_final = calcular_precio_total(prod,unidades);
*valor_total = *valor_total + valor_final;
return *valor_total;
}

void finTicket (double *valor_total, int numTicket, char nomArch[50])
{
double precio_iva;

precio_iva = *valor_total * IVA;
*valor_total = *valor_total + precio_iva;

FILE * NOM[numTicket];

NOM[numTicket] = fopen(nomArch, "a");

if(NOM[numTicket] == NULL)
{
printf("Error al abrir el fichero.");
}
else
{
fprintf(NOM[numTicket], "\n");
fprintf(NOM[numTicket], "%*s\t%6s\t%6.2lf\tEur\n", 21,
"8%", "IVA" ,precio_iva);
fprintf(NOM[numTicket], "%*s\t%6.2lf\tEur\t",30,
"TOTAL", *valor_total);
}
fclose(NOM[numTicket]);
}


//Programa principal
int main (void)
{
struct productos prod;
double valor_total;
char codigoLeidoTeclado[MAX_LONG];
char nomArch[50];
int cnt=0;
int existe = 0;
int unidades = 0;
int numTicket = 1;
int n;



while(1)
{
sprintf(nomArch,"ticket%d.txt", numTicket);
printf("Codigo de producto (0 - finalizar compra): ");
scanf("%s", codigoLeidoTeclado);
// crearFichero(numTicket, nomArch);

//Función que escribe cabecera de ticket
cabecera_ticket(numTicket, nomArch);

//Esto compara el codigo del producto y cuando es 0 finaliza
while(strcmp(codigoLeidoTeclado, "0") == 1)
{
// Función que lea datos de productos del fichero
cnt=buscar_producto(&prod ,codigoLeidoTeclado, &n);
//Si existe el producto pediremos el numero de unidades
if (existe==1)
{
//Procedimiento para escribir los productos en pantalla
escribir_producto(&prod,codigoLeidoTeclado,n);
//Unidades
printf("Unidades: ");
scanf("%d", &unidades);

//Función que escribe  los productos en el ticket
generar_linea(&prod,codigoLeidoTeclado,
 unidades, numTicket, nomArch);
totalFinal (&prod,unidades, &valor_total);
}
else
{
printf("El producto introducido no existe");
}
printf("Codigo de producto (0 - finalizar compra): ");
scanf("%s", codigoLeidoTeclado);
}
// finTicket (&valor_total,numTicket, nomArch);
printf("Generado ticket %d \n", numTicket);

numTicket++;
valor_total = 0;
}
}

Alguna de las dudas que tengo después de esto es que sintácticamente no se escrbir muy bien los struct y no se muy bien como van. Pero bueno si me puedes ayudar, te lo agradecería, porque estoy desesperado ya  :-[

skapunky

Deberás realizar el programa que guarde la estructura con punteros ya que si lo haces en un array el problema será que dependerás de un numero máximo de productos a registrar.

La estructura puede ser:

Código (cpp) [Seleccionar]
struct productos {
int *codigo;
char nombre[20];
int precio;
}


Tu archivo txt deberá seguir esta estructura anterior, guardando el codigo/nombre/precio. Para cargar el archivo lo unico que deberás hacer es ir cargando los datos del archivo al struct.

Esto es mas facil si partes de cero, es decir si tienes el struct creado, guardas el codigo/nombre/precio de un producto y luego lo cargas mediante otra función que lea el txt y recupere la información.

En tu caso no se si deseas leer la información de un txt ya relleno o tu propio programa debe ingresar los productos y luego recuperarlos..si es así utiliza un struct con un puntero.



Killtrojan Syslog v1.44: ENTRAR

moralescmj

Lo que el programa debe hacer es leer un fichero previamente creado llamado "productos.txt" en el cual aparecen los productos de esta forma:

03FX TOMATES 6.50
ASDF DICCIONARIO 8.56
1234 LIBRO 1.50

Y principalmente lo que mas me cuesta es intentar meter esos datos en un struct y que el programa lea todo a partir de este. El unico dato a manipular del fichero sería el precio, ya que luego tengo que crear un fichero nuevo(que sería el ticket) en el cual saldrían los productos elegidos por su codigo y su precio total.
Todo esto me funcionaba bien hasta que me mandaron modificarlo para que hiciera lo del struct. Y ahora mismo con los apuntes que tenemos de clase, como que no podríamos hacer absolutamente nada... Por eso pido ayuda.
Muchas gracias