Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Elyic en 18 Mayo 2017, 08:20 am



Título: Problema al modificar registro en un archivo
Publicado por: Elyic en 18 Mayo 2017, 08:20 am
Hola buenas noches, quisiera que me ayudaran con un problema que tengo al usar la funcion fseek para modificar cierto registro en un archivo txt, el problema es que cuando ingreso un "ID" que no sea 1, no me toma ninguna registro, si pudieran ayudarme se los agradeceria mucho :)

Código:
#include <iostream>
#include <conio>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <ctype.h>
FILE *FMaterial = NULL;
struct Material
{
int iID;
   char cNombre[25];
   int iExist;
   float fPrecioC;
   int iExistm;
   char cDescrip[30];
   float fPrecioV;
   int iEliminado;
};
void modificar()
{
clrscr();
Material material;
int auxID;
cout<<"ID Material: ";
cin>>auxID;
FMaterial = fopen("Material.txt","r+");
if (FMaterial == NULL)
{
cout<<"No hay registros en el archivo...\n";
}else
{
fseek(FMaterial, (long)(auxID-1)* sizeof(Material), 0);
fread(&material, sizeof(Material),1,FMaterial);
cout<<"Nombre: "material.cNombre<<"\n";
fclose(FMaterial);
}
}
void main()
{
modificar();
getch();
}


Título: Re: Problema al modificar registro en un archivo
Publicado por: MAFUS en 18 Mayo 2017, 15:18 pm
Y una copia del archivo, sino no podemos probar.

Ahora que me fijo: buscas datos binarios en el archivo pero lo abres para texto, por eso tienes problemas a la hora de conseguir datos.


Título: Re: Problema al modificar registro en un archivo
Publicado por: Elyic en 18 Mayo 2017, 17:33 pm
Gracias por responder, que deberia cambiar en el codigo?
https://mega.nz/#!LgIzQQTT!2K7-cx9Hh5KuoaJDJFt77pwpyLEJn1glII4crufymLM (https://mega.nz/#!LgIzQQTT!2K7-cx9Hh5KuoaJDJFt77pwpyLEJn1glII4crufymLM)
Aqui dejo el archivo de texto de donde intento sacar los datos, solo tiene 2 registros.


Título: Re: Problema al modificar registro en un archivo
Publicado por: MAFUS en 18 Mayo 2017, 20:06 pm
Vale, tienes un pequeño problema pero es muy engorroso. No es difícil de arreglar, pero sí que conlleva escribir bastante código y a estructuras más grandes más código a escribir.

Verás. Se llama memory padding, en español acomodación de la memoria. ¿De qué se trata?

C, y por extensión C++, vienen de un tiempo donde la memoria era algo precioso (escasa y cara) y los procesadores eran muy lentos por lo que el lenguaje mismo ayudaba a que los datos, estructuras, ocuparan lo mínimo posible pero al mismo tiempo que el acceso a sus datos fuera lo más rápido posible. Así que acomodaba los datos, no en el orden que había dictado el programador, sino que hacía que quedaran múltiplos al tamaño de palabra del procesador y con el menor número de huecos posibles. Ya, suena complicado, para entenderlo te invito a que profundices en manejo de memoria por parte de C.

¿En qué te afecta? Cuando tienes una estructura y la quieres copiar toda de una vez en un archivo C, y por extensión C++, copiará literalmente esa porción de memoria en el archivo y lo hará todo lo desordenada (para él ordenada) que sea, así que los campos en el disco no están como esperas. De esta forma cuándo vayas a sacarlos y copiarlos de nuevo a una estructura copiará tal cual del disco y lo situará en la porción de memoria que tienes byte a byte. Un desastre.

¿Qué puedes hacer? Existen extensiones del compilador, y por tanto no es portable el código, que aseguran que en memoria los datos van a estar tal cual lo has escrito en el código.
O
Una forma más portable, es copiar uno a uno los campos de la estructura en el disco y, a la hora de leerlos, adquirirlos uno a uno llenando así la estructura destino.


Título: Re: Problema al modificar registro en un archivo
Publicado por: Elyic en 18 Mayo 2017, 22:19 pm
Muchisimas gracias por la ayuda/explicacion, te cuento que pude arreglar el error gracias a lo que me dijiste de que estaba buscando datos en binario, cambie la forma de guardar los datos envés de usar ".txt" lo cambie a ".bin".
Adjunto el codigo para que veas lo que modifique.
Ingreso
Código:
#include <iostream>
#include <conio>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <ctype.h>
FILE *FMaterial = NULL;
struct Material
{
int iID;
   char cNombre[25];
   int iExist;
   float fPrecioC;
   int iExistm;
   char cDescrip[30];
   float fPrecioV;
   int iEliminado;
};
void vingresomat()
{
Material material;
   clrscr();
   fflush(stdin);
   cout<<"\t||=====Ingreso de datos=====\n";
   cout<<"\t||Nombre: ";
   fgets(material.cNombre,sizeof(material.cNombre),stdin);
   if(material.cNombre[strlen(material.cNombre)-1]=='\n')
   {
    material.cNombre[strlen(material.cNombre)-1] = '\0';
   }
   fflush(stdin);
   cout<<"\t||Existencia: ";
   cin>>material.iExist;
   fflush(stdin);
   cout<<"\t||Precio Costo: Q";
   cin>>material.fPrecioC;
   fflush(stdin);
   cout<<"\t||Existencia Minima: ";
   cin>>material.iExistm;
   cout<<"\t||Descripcion: ";
   fgets(material.cDescrip,sizeof(material.cDescrip),stdin);
   if(material.cDescrip[strlen(material.cDescrip)-1] == '\n')
   {
    material.cDescrip[strlen(material.cDescrip)-1] = '\0';
   }
   cout<<"\t||Precio de Venta: Q";
   cin>>material.fPrecioV;
   material.iEliminado=0;
   FMaterial = fopen("Material.bin", "r");
   if(FMaterial==NULL)
   {
    FMaterial = fopen("Material.bin","a+b");
      material.iID=1;
      fwrite(&material,sizeof(Material),1,FMaterial);
      fclose(FMaterial);
   }else
   {
    fclose(FMaterial);
      FMaterial=fopen("Material.bin","a+b");
      fseek(FMaterial,0,SEEK_END);
      material.iID=(ftell(FMaterial)/sizeof(Material))+1;
      rewind(FMaterial);
      fwrite(&material,sizeof(Material),1,FMaterial);
      fclose(FMaterial);
   }
}
void main()
{
   vingresomat();
getch();
}
Mostrar
Código:
#include <iostream>
#include <conio>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <ctype.h>
FILE *FMaterial = NULL;
struct Material
{
int iID;
   char cNombre[25];
   int iExist;
   float fPrecioC;
   int iExistm;
   char cDescrip[30];
   float fPrecioV;
   int iEliminado;
};
void vreportemat()
{
Material material;
clrscr();
   FMaterial = fopen("Material.bin", "r");
   if (FMaterial == NULL)
   {
    cout<<"No se han ingresado datos....\n";
   }else
   {
   cout<<"\t||=======Datos=======\n";
   fread(&material,sizeof(Material),1,FMaterial);
   while(feof(FMaterial)== 0)
   {
   if (material.iEliminado==0)
   {
   cout<<"\t||ID: "<<material.iID;
   cout<<"\n\t||Nombre: "<<material.cNombre;
   cout<<"\n\t||Existencia: "<<material.iExist;
   cout<<"\n\t||Precio Costo: Q."<<material.fPrecioC;
   cout<<"\n\t||Existencia Minima: "<<material.iExistm;
   cout<<"\n\t||Descripcion: "<<material.cDescrip;
   cout<<"\n\t||Precio de Venta: Q."<<material.fPrecioV;
   cout<<"\n\t||======================================\n";
   }
   fread(&material,sizeof(Material),1,FMaterial);
   }
   }
   fclose(FMaterial);
getch();
}
void main()
{
vreportemat();
}
Modificar
Código:
#include <iostream>
#include <conio>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <ctype.h>
FILE *FMaterial = NULL;
struct Material
{
int iID;
   char cNombre[25];
   int iExist;
   float fPrecioC;
   int iExistm;
   char cDescrip[30];
   float fPrecioV;
   int iEliminado;
};
void modificar()
{
clrscr();
Material material;
int auxID;
cout<<"ID Material: ";
cin>>auxID;
FMaterial = fopen("Material.bin","r+");
if (FMaterial == NULL)
{
cout<<"No hay registros en el archivo...\n";
}else
{
fseek(FMaterial, (long)(auxID-1)* sizeof(Material), 0);
fread(&material, sizeof(Material),1,FMaterial);
cout<<"Nombre: "<<material.cNombre<<"\n";
fclose(FMaterial);
}
}
void main()
{
modificar();
getch();
}