Autor Tema: Ejemplo clase C++ leer datos desde fichero, insertar, buscar modificar cplusplus  (Leído 22597 veces)

chica_ing

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 7
    • Ver Perfil
Hola me podéis ayudar con el método modificar, le he dado muchas vueltas pero no consigo que funciones. esto es lo que llevo hecho de mi programa en c++.

Código: [Seleccionar]
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include "clinica.h"


using namespace std;
typedef char DATA_TYPE;

/*Un objeto Clínica está vinculado a un fichero, siendo el constructor el método en el que se
debe abrir tal fichero, según la cadena pasada como parámetro (con el nombre del fichero
físico). Si tal fichero ya existiera se leería el valor de numPacientes, y si no, se procedería a
crearlo (asignando y guardando el valor de 0 para el número de pacientes).*/
clinica::clinica(char nombrefichero[]){

//abrir ficheo y cargar numero de pacientes, si no existe, que este a 0
fichero.open(nombrefichero,ios::binary|ios::in|ios::out);
if(!fichero.fail())
{
fichero.read((char*) &numpacientes, sizeof(numpacientes));

//fichero.close();
}
else
{
cout<<"Error en la apertura del fichero\n";

FILE *ffichero2;

ffichero2=fopen(nombrefichero, "w+b");
fputc(0,ffichero2);
numpacientes=0;
fclose(ffichero2);
/* fstream fichero2;//creamos fichero2
fichero2.open(nombrefichero,ios::binary|ios::in|ios::out);//abrimos el fichero2 en modo binario
fichero2<<"0"<<endl;//Escibimos un 0
numpacientes=0;
fichero2.close(); cerramos el fichero2*/
}

};


/*El método privado posicionar se encarga de situarse en el fichero en el inicio del paciente p
pasado como parámetro. Dicho método recibe como parámetro, bajo el parámetro oper,
valores ‘R’ para posicionamiento para lectura o de ‘W’ para posicionamiento para escritura.*/

void clinica::posicionar(int p, char oper){

paciente pa;
int num;

fichero.seekg(0, ios::beg);
fichero.read((char*) &num, sizeof(int));

for(int i=0;i<num-2;i++){
fichero.read((char*) &pa, sizeof(pa));
cout <<"paciente-->"<< pa.id <<"  "<<pa.nombre<<endl;
}

fichero.read((char*) &pa, sizeof(pa));
cout << pa.id <<endl;

};
/*El método consultar se encarga de mostrar por pantalla los datos de todos los pacientes cuyos
apellidos comiencen por el carácter pasado por parámetro (si nos pasan * sería mostrar todos).*/
void clinica::consultar(char inicial){

paciente pa;
int num;

fichero.seekg(0, ios::beg);
fichero.read((char*) &num, sizeof(num));

for(int i=0;i<num;i++){
   fichero.read((char*) &pa, sizeof(pa));
   
   if(inicial=='*')
   {
    cout<<pa.apellidos<<endl;
   }
   else
   {
   
    if(inicial==pa.apellidos[0])
{

cout<<"El apellido que comienza por la "<<inicial<< " es "<<pa.apellidos<<endl<<endl;
}
}
}

};

/*
El método insertar realiza la inserción de los datos de un nuevo paciente, a continuación del
último de los ya existentes.
*/

void clinica::insertar(paciente p){

fichero.seekg(0, ios::end);
fichero.write((char*) &p, sizeof(p));

numpacientes=numpacientes+1;
fichero.seekg(0, ios::beg);

fichero.write((char*) &numpacientes, sizeof(numpacientes));


};


/*El método modificar se encarga de actualizar los datos del paciente cuyo identificador se pasa
por parámetro, pidiendo dichos datos previamente. Si el identificador no estuviera en el
fichero de pacientes, se mostraría un mensaje al respecto.*/

void clinica::modificar(int id){

paciente pa;
int num=0;


fichero.seekg(0, ios::beg);

            fichero.read((char*) &pa, sizeof(pa));
if(pa.id==id)
{

cout<<"\nIndique nombre a actualizar: ";    cin>>pa.nombre;
cout<<"\nIndique apellidos a actualizar: "; cin>>pa.apellidos;
cout<<"\nIndique el id a actualizar: ";     cin>>pa.id;
cout<<"\nIndique la edad a actualizar: ";   cin>>pa.edad;
fichero.write((char*) &pa, sizeof(pa));
}
else
cout<<"\nError, no se encontró ningún paciente con el id introducido. ";


};

Muchas gracias.
« Última modificación: 11 de Mayo 2015, 18:54 por Alex Rodríguez »

Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
Hola, ¿puedes poner un ejermplo de fichero con datos? Aquí puedes ver cómo adjuntar el fichero

Y también, ¿puedes poner un ejemplo de programa donde se utilice esta clase? (pegar el código)

Salu2

chica_ing

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 7
    • Ver Perfil
Hola, ¿puedes poner un ejermplo de fichero con datos? Aquí puedes ver cómo adjuntar el fichero

Y también, ¿puedes poner un ejemplo de programa donde se utilice esta clase? (pegar el código)

Salu2



Gracias por responder. Te envío el .cpp, .h y el enunciado

Este es el .cpp:

Código: [Seleccionar]
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include "clinica.h"


using namespace std;
typedef char DATA_TYPE;

/*Un objeto Clínica está vinculado a un fichero, siendo el constructor el método en el que se debe abrir tal fichero, según la cadena pasada como parámetro (con el nombre del fichero físico). Si tal fichero ya existiera se leería el valor de numPacientes, y si no, se procedería a crearlo (asignando y guardando el valor de 0 para el número de pacientes).*/
clinica::clinica(char nombrefichero[]){

//abrir fichero y cargar numero de pacientes, si no existe, que este a 0
fichero.open(nombrefichero,ios::binary|ios::in|ios::out);
if(!fichero.fail())
{
fichero.read((char*) &numpacientes, sizeof(numpacientes));

//fichero.close();
}
else
{
cout<<"Error en la apertura del fichero\n";

FILE *ffichero2;

ffichero2=fopen(nombrefichero, "w+b");
fputc(0,ffichero2);
numpacientes=0;
fclose(ffichero2);
/* fstream fichero2;//creamos fichero2
fichero2.open(nombrefichero,ios::binary|ios::in|ios::out);//abrimos el fichero2 en modo binario
fichero2<<"0"<<endl;//Escibimos un 0
numpacientes=0;
fichero2.close(); cerramos el fichero2*/
}

};


/*El método privado posicionar se encarga de situarse en el fichero en el inicio del paciente p pasado como parámetro. Dicho método recibe como parámetro, bajo el parámetro oper, valores ‘R’ para posicionamiento para lectura o de ‘W’ para posicionamiento para escritura.*/

void clinica::posicionar(int p, char oper){

paciente pa;
int num;

fichero.seekg(0, ios::beg);
fichero.read((char*) &num, sizeof(int));

for(int i=0;i<num-2;i++){
fichero.read((char*) &pa, sizeof(pa));
cout <<"paciente-->"<< pa.id <<"  "<<pa.nombre<<endl;
}

fichero.read((char*) &pa, sizeof(pa));
cout << pa.id <<endl;

};
/*El método consultar se encarga de mostrar por pantalla los datos de todos los pacientes cuyos apellidos comiencen por el carácter pasado por parámetro (si nos pasan * sería mostrar todos).*/
void clinica::consultar(char inicial){

paciente pa;
int num;

fichero.seekg(0, ios::beg);
fichero.read((char*) &num, sizeof(num));

for(int i=0;i<num;i++){
   fichero.read((char*) &pa, sizeof(pa));
   
   if(inicial=='*')
   {
    cout<<pa.apellidos<<endl;
   }
   else
   {
   
    if(inicial==pa.apellidos[0])
{

cout<<"El apellido que comienza por la "<<inicial<< " es "<<pa.apellidos<<endl<<endl;
}
}
}

};

/*
El método insertar realiza la inserción de los datos de un nuevo paciente, a continuación del último de los ya existentes.
*/

void clinica::insertar(paciente p){

fichero.seekg(0, ios::end);
fichero.write((char*) &p, sizeof(p));

numpacientes=numpacientes+1;
fichero.seekg(0, ios::beg);

fichero.write((char*) &numpacientes, sizeof(numpacientes));


};


/*El método modificar se encarga de actualizar los datos del paciente cuyo identificador se pasa por parámetro, pidiendo dichos datos previamente. Si el identificador no estuviera en el fichero de pacientes, se mostraría un mensaje al respecto.*/

void clinica::modificar(int id){
           
};

Este es el .h:

Código: [Seleccionar]
#include <fstream>
#include <iostream>
using namespace std;

const int TAM_CADENA = 30;
typedef char cadena[TAM_CADENA];

struct paciente{
int id;
cadena nombre;
cadena apellidos;
int edad;
};//nombre de la variable

class clinica{
private:
fstream fichero;
int numpacientes;
//void posicionar(int p, char oper);

public:
void posicionar(int p, char oper);
clinica(char nombrefichero[]);
int getnumpacientes()
{
return numpacientes;
};
void consultar(char inicial);
void insertar(paciente p);
void modificar(int id);
void eliminar(int id);
void simularoperaciones();

};

El enunciado lo intentaré subir luego

Muchas gracias.
« Última modificación: 03 de Diciembre 2020, 13:04 por César Krall »

chica_ing

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 7
    • Ver Perfil
Por favor alguien que pueda ayudarme?
Gracias

Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
Hola, ¿dónde tienes el archivo con el método main?, es decir, ¿cómo ejecutas el programa para probarlo?

Salu2

chica_ing

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 7
    • Ver Perfil
Hola, muchísimas gracias por responde. He conseguido hacer el método modificar. Ahora lo que me da un fallo es el eliminar.
Lo que hago es introducir el id del paciente que quiero eliminar, lo coge, se posiciona en el que quiero eliminar y desplaza el resto d pacientes. Pero cuando le doy a la opción de consultar, para ver si el eliminar se ha hecho correctamente, me pilla como basura.
Por favor, podéis echarle un vistazo, haber que me puede estar fallando.

Este es el .cpp
Código: [Seleccionar]
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include "clinica.h"


using namespace std;
typedef char DATA_TYPE;

/*Un objeto Clínica está vinculado a un fichero, siendo el constructor el método en el que se
debe abrir tal fichero, según la cadena pasada como parámetro (con el nombre del fichero
físico). Si tal fichero ya existiera se leería el valor de numPacientes, y si no, se procedería a
crearlo (asignando y guardando el valor de 0 para el número de pacientes).*/
clinica::clinica(char nombrefichero[]){

//abrir ficheo y cargar numero de pacientes, si no existe, que este a 0
fichero.open(nombrefichero,ios::binary|ios::in|ios::out);
if(!fichero.fail())
{
fichero.read((char*) &numpacientes, sizeof(numpacientes));

//fichero.close();
}
else
{
cout<<"Error en la apertura del fichero\n";

FILE *ffichero2;

ffichero2=fopen(nombrefichero, "w+b");
fputc(0,ffichero2);
numpacientes=0;
fclose(ffichero2);
/* fstream fichero2;//creamos fichero2
fichero2.open(nombrefichero,ios::binary|ios::in|ios::out);//abrimos el fichero2 en modo binario
fichero2<<"0"<<endl;//Escibimos un 0
numpacientes=0;
fichero2.close(); cerramos el fichero2*/
}

};


/*El método privado posicionar se encarga de situarse en el fichero en el inicio del paciente p
pasado como parámetro. Dicho método recibe como parámetro, bajo el parámetro oper,
valores ‘R’ para posicionamiento para lectura o de ‘W’ para posicionamiento para escritura.*/

void clinica::posicionar(int p, char oper){

paciente pa;
int num;
int i=0;//indice

fichero.seekg(0, ios::beg);
fichero.read((char*) &num, sizeof(int));


while(i<num){

fichero.read((char*) &pa, sizeof(pa));
cout <<"paciente-->"<< pa.id <<"  "<<pa.nombre<<endl;

if(pa.id==p){

if(oper=='W'){
fichero.seekp(0,ios::cur);//Se ha posicionado correctamente para la escritura
break;
}else if(oper=='R'){
fichero.seekg(0,ios::cur);//Se ha posicionado correctamente para la lectura
break;
}
}
i++;
}
if(i==num){
fichero.seekg(0, ios::beg);
cout<<"No se encuentra el paciente"<<endl;
}

};
/*El método consultar se encarga de mostrar por pantalla los datos de todos los pacientes cuyos
apellidos comiencen por el carácter pasado por parámetro (si nos pasan * sería mostrar todos).*/
void clinica::consultar(char inicial){

paciente pa;
int num;

fichero.seekg(0, ios::beg);
fichero.read((char*) &num, sizeof(num));
cout<<num<<endl;
system("pause");

for(int i=0;i<num;i++){
   fichero.read((char*) &pa, sizeof(pa));
   
   if(inicial=='*')
   {
    cout<<pa.apellidos<<pa.id<<endl;
    system("pause");
   }
   else
   {
   
    if(inicial==pa.apellidos[0])
{

cout<<"El apellido que comienza por la "<<inicial<< " es "<<pa.apellidos<<endl<<endl;
}
}
}

};

/*
El método insertar realiza la inserción de los datos de un nuevo paciente, a continuación del
último de los ya existentes.
*/

void clinica::insertar(paciente p){

fichero.seekg(0, ios::end);
fichero.write((char*) &p, sizeof(p));

numpacientes=numpacientes+1;
fichero.seekp(0, ios::beg);

fichero.write((char*) &numpacientes, sizeof(numpacientes));


};


/*El método modificar se encarga de actualizar los datos del paciente cuyo identificador se pasa
por parámetro, pidiendo dichos datos previamente. Si el identificador no estuviera en el
fichero de pacientes, se mostraría un mensaje al respecto.*/

void clinica::modificar(int id){

paciente pa;

posicionar(id,'W');

pa.id=id;
cout<<"Dame nombre del paciente"<<endl;
cin>>pa.nombre;
cout<<"Dame apellidos del paciente"<<endl;
cin>>pa.apellidos;
cout<<"Dame edad del paciente"<<endl;
cin>>pa.edad;

fichero.write((char*) &pa, sizeof(pa));

cout<<"La escritura se ha hecho correctamente"<<endl;



};

/*El método eliminar realiza la eliminación del paciente cuyo identificador se pasa por
parámetro. Si el identificador no estuviera en el fichero de pacientes, se mostraría un mensaje
al respecto. Para eliminar un paciente del fichero, se desplazan una posición a la izquierda
todos los pacientes existentes a continuación del que se elimina (para no dejar huecos).*/
void clinica::eliminar(int id){

paciente pa;

posicionar(id,'W');

// fichero.read((char*) &pa, sizeof(pa));
int pos=0;
// fichero.seekg(0,ios::cur);
//cout<<"llego"<<endl;

while(fichero.eof()==0){
cout<<"entro en el while"<<endl;
fichero.read((char*) &pa, sizeof(pa));
cout<<"he leido"<<pa.id<<endl;
fichero.seekp(-sizeof(pa),ios::cur);
fichero.write((char*) &pa, sizeof(pa));
cout<<"he escrito"<<pa.id<<endl;

//pos++;
//fichero.seekg(sizeof(pa),ios::cur);
//system("pause");

}
fichero.seekp(0,ios::beg);
fichero.seekg(0,ios::beg);
numpacientes--;
fichero.write((char*) &numpacientes, sizeof(int));



};

Desde el main llamo al método asi:

   case 4:
         cout<<"Introduzca id:"<<endl;
         cin>>id;
         cli.eliminar(id);
         break;

Gracias.

Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
Hola pero ¿dónde está el código del main? No lo veo  ::)

chica_ing

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 7
    • Ver Perfil
Código: [Seleccionar]
#include <iostream>
#include <fstream>
#include "clinica.h"

using namespace std;


int main() {

int opcion;
char c []="clinica" ;//para comprobar que no existe ponemos clinica1
clinica cli(c);



do{

cout<<"El numero de pacientes es:"<<endl;
cout<<cli.getnumpacientes()<<endl<<endl;


cout<<"CLINICA 'Los Milagros'"<<endl;
cout<<"----------------------"<<endl;

cout<<"1. Consultar pacientes"<<endl;
cout<<"2. Introducir un nuevo paciente"<<endl;
cout<<"3. Modificar un paciente"<<endl;
cout<<"4. Eliminar un paciente"<<endl;
cout<<"5. Simular operaciones."<<endl;
cout<<"6. Posicionar."<<endl;
cout<<"7. Salir"<<endl;

cout<<"Elige una opción:"<<endl;
cin>>opcion;



switch(opcion){
case 1:
char inicial;
cout<<"Introduzca la inicial del apellido que desea buscar \n o pulse '*' para mostrar todos:\n"<<endl;
cin>>inicial;
cli.consultar(inicial);

break;
case 2:
paciente p;
cout<<"Introduzca el ID del paciente:";
cin>>p.id;
cout<<"Introduzca el Nombre del paciente:";
cin>>p.nombre;
cout<<"Introduzca los Apellidos del paciente:";
cin>>p.apellidos;
cout<<"Introduzca la Edad del paciente:";
cin>>p.edad;

cout<<"El nuevo paciente es"<<endl<<p.id<<endl<<p.nombre<<endl<<p.apellidos<<endl<<p.edad<<endl;
cli.insertar(p);

break;
    case 3:
    int id;
    cout<<"Introduzca el id del paciente que desea modificar:"<<endl;
cin>>id;
    cli.modificar(id);
break;
case 4:
cout<<"Introduzca id:"<<endl;
cin>>id;
cli.eliminar(id);
break;
case 5:

break;
/*case 6:
int recoge_id;
cout<<"Elige un paciente:"<<endl;
cin>>recoge_id;
cli.posicionar(recoge_id, 'W');
break;*/
case 6:
cout<<"Hasta pronto\n";
system("pause");
break;
default:
cout<<"La opcion es incorrecta\n";
system("pause");
break;
}
}while(opcion != 6);


}

Ese es el main.
Gracias por responder.

Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
Al ejecutar el main me salta un error "undefined reference", puede ser porque me falte el fichero clinica, supongo que para ejecutar tienes un fichero clinica con datos de ejemplo?

Salu2

chica_ing

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 7
    • Ver Perfil
Hola gracias por responder. Hace un ratito he conseguido por fin hacer el método. Estoy haciendo otra parte, que es la parte quirofano. Si me surge alguna duda acudiré a vosotros. Muchisímas gracias.

Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
Hola, simplemente para salir de la duda ¿el error que me estaba dando es porque falta el fichero?

chica_ing

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 7
    • Ver Perfil
Hola Ogramar, si, el error del main te sale porque falta el fichero clinica, donde hay insertado 5 pacientes. :)

Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
¿Puedes ponerlo como archivo adjunto? (Aquí se explica cómo -- https://www.aprenderaprogramar.com/foros/index.php?topic=1460.0)

Salu2

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".