Archivos binarios

Iniciado por Beginner Web, 5 Octubre 2018, 11:49 AM

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

Beginner Web

Hola, miren no se que estoy haciendo mal a  la hora de agregar un nuevo registro, quiero que guardar registros de alumnos teniendo en cuenta que sus codigo de alumno no se deben repetir, no se que estoy haciendo mal  :(

Código (cpp) [Seleccionar]
#include <stdio.h>
#include <stdlib.h>
#include <iostream>

using namespace std;

typedef char tcad[50];
typedef struct talumno{
int libreta;
tcad nombre;
tcad carrera;
};
typedef FILE *parchivo;

void carga(talumno &a);
void cargar_alumnos(parchivo alumnos);
void mostrar(parchivo alumnos);
void borrar(parchivo alumnos, int buscado);
bool consulta(parchivo alumnos, int codigo);

main()
{
int codigoBuscado;
parchivo estudiantes;
cargar_alumnos(estudiantes);
mostrar(estudiantes);
cout<<"Buscar alumno, ingrese LU: ";cin>>codigoBuscado;
borrar(estudiantes,codigoBuscado);
system("pause");
}

void carga(talumno &a)
{
fflush(stdin);
cout<<"Ingrese LU: ";cin>>a.libreta;
fflush(stdin);
cout<<"Ingrese nombre: ";gets(a.nombre);
fflush(stdin);
cout<<"Ingrese carrera: ";gets(a.carrera);
fflush(stdin);
}

void cargar_alumnos(parchivo alumnos)
{
talumno a;
int cantidad;
alumnos=fopen("alumnos.txt","wb");//Modo escritura, se pierde el contenido, si no existe el archivo lo crea
cout<<"Cuantos registros desea guardar?: ";cin>>cantidad;
while(cantidad>0){
carga(a);
if(consulta(alumnos,a.libreta)==false){
fwrite(&a,sizeof(a),1,alumnos);
cantidad--;
}
else{
cout<<"YA EXISTE UN USUARIO CON LA MISMA LIBRETA"<<endl;
}
}
fclose(alumnos);
}

void mostrar(parchivo alumnos)
{
talumno a;
alumnos=fopen("alumnos.txt","rb");//Apertura solo modo escritura
if(alumnos==NULL){
cout<<"Archivo inexistente"<<endl;
}
else{
while(!feof(alumnos)){
fread(&a,sizeof(a),1,alumnos);
if(!feof(alumnos)){
cout<<a.libreta<<endl;
cout<<a.nombre<<endl;
cout<<a.carrera<<endl;
}
}
}
fclose(alumnos);
}

void borrar(parchivo alumnos, int buscado)//Copia todos los alumnos excepto uno en especifico y lo guarda en otro archivo temporal
{
talumno a;
parchivo aux;
alumnos=fopen("alumnos.txt","rb");
aux=fopen("temporal.txt","wb");
if(alumnos!=NULL){
while(!feof(alumnos)){
fread(&a,sizeof(a),1,alumnos);
if(a.libreta!=buscado && !feof(alumnos)){
fwrite(&a,sizeof(a),1,aux);
}
}
fclose(aux);
fclose(alumnos);
}
if(remove("alumnos.txt")==0){//Desde aqui borra el archivo original y renombra el archivo temporal a "alumnos.txt"
cout<<"ELIMINADO EXITOSAMENTE"<<endl;
if(rename("temporal.txt","alumnos.txt")==0){
cout<<"RENOMBRADO EXITOSAMENTE"<<endl;
}
else{
cout<<"ERROR AL RENOMBRAR"<<endl;
}
}
else{
cout<<"ERROR AL ELIMINAR"<<endl;
}
}

bool consulta(parchivo alumnos, int codigo)
{
talumno a;
bool existe=false;
alumnos=fopen("alumnos.txt","rb");
if(alumnos!=NULL){
while(!feof(alumnos) && existe==false){
fread(&a,sizeof(a),1,alumnos);
if(a.libreta==codigo){
existe=true;
}
}
}
fclose(alumnos);
return existe;
}
7w7

OmarHack

Si me indicas lo siguiente te ayudo:
Cual es la parte del código que te da problemas?
Qué problemas te da?
Que quieres que haga esa parte de código que no hace?

Es que no tengo ningún compilador a mano en este sistema.
I like to test things.

Serapis

Debes intentar aprender a atrapar tu mismo los errores sencillos...
Por ejemplo, si ya has introducido un código (por ejemplo 56), repite más tarde el mismo código a ver si lo hace bien, si lo hac emal y lo añade, entonces te vas primero a la parte d ela función que búsqueda que compara el solicitado con el existente, es decir aquí:


while(!feof(alumnos) && existe==false){
fread(&a,sizeof(a),1,alumnos);
                        // imprimir s.libreta y codigo
if(a.libreta==codigo){
existe=true;
}
                        // en la misma línea, imprimir el resultadod e la comparación (el valor de existe)
}

He añadido dos líneas comentadas, sustitúyelas por el código correspondiente.... y entonces podrás ver qué pasa, primero viendo si los valores de libreta corresponden con los que has introducido previamente y segundo viendo si el nuevo 'código', se corresponde con el pasado a la función... si ambos son iguales,  la comparación debe arrojar true, si no es así, o los valores no corresponden con los introducidos, tendrás un erro en alguna sección previa.

Y de paso aprovecho para comentarte que no es buena idea que una función se llame existe y dentro (privada) de ella declares una variable con el mismo nombre, se presta a copnfusión, salvo que hayas agotado todos los nombres posibles (imposible verdad?), porque otorgarle el mismo nombre... siendo privado, cambialo por ejemplo por 'bool hallado=false;' significa lo mismo, pero quien lea (otro que no seas tú, no precisan perder más tiempo en verificaciones innecesarias).

...pero vamos, la idea es que aprendas a colocar líneas de código dentro del código, con el único propósito de detectar tus propios errores... una vez detectado, dichas líneas las comentas y cuando lo des por terminado, si quieres hasta puedes borrarlas...

Beginner Web

Bueno la funcion consulta no me esta retornando valores validos, en un momento mi codigo retornaba puros 0 ahora retorna puros 1
7w7

OmarHack

Cual es la función consulta? No la veo.
I like to test things.

Beginner Web

NEBIRE, solo me lee el primer elemento del archivo los demas no, esta bien el recorrido o tengo que hacer otro especial para archivos binarios?
7w7

Beginner Web

Bueno, ya encontre el error no era lo que decian por aca, ahora quiero que los que piensen sean ustedes, no hace falta que me digan como arreglar el error, como mucho se puede decir la linea donde esta el error nada mas(faltan dos funciones, o sea 2 lineas de codigo)  ;-)
7w7

OmarHack

No me gusta mirar el código de los demás. Soy muy obsesivo con el orden, formato y limpieza en estas cosas.
I like to test things.

MAFUS

Ahora la segunda parte.
Ahora que ya te desenvuelves bien con la programación debes pasar a las buenas costumbres:

Toda función debe tener el tipo devuelto en su definición o declaración:
main() {
...
Está mal, es un estándar pre ansietat de hace treinta años.

No uses typedef para ocultar cosas: FILE todos sabemos que es y que esperar cuando lo vemos, parchivo no. Sigue usando FILE.
De igual modo no ocultes punteros: uno ve un puntero y sabe a qué atenerse, si no está el puntero ¿Se trata de una variable normal? Fíjate que las librerías estándar no lo ocultan y en C++ implementaron el paso por referencia para hacer el cometido.

Sí usas C++ lleva todo lo posible a ese lenguaje: por ejemplo ya no uses más typedef tcad[50], en su lugar tienes los strings que hacen la misma función, o mejor. Con los archivos igual.

Estás mezclando C, C++, estilos de hace 30 años. Es hora de centrarte en C++ y sacarle todo el provecho.

Beginner Web

Esta bien MAFUS, quiero agarrar la logica primero luego me centrare en eso, ademas asi nos estan ennseñando en el secundario, voy a primer año  ;-)
7w7