PDA

Ver la Versión Completa : Problemas con C++Builder 6


aguml
06-12-2016, 12:05:56
Hola amigos estoy teniendo problemas con una prueba que estoy haciendo con clases en C++Builder 6 y no acabo de ver el problema. Este es todo el codigo que llevo:
Main.cpp:
#include <iostream>
#include <fstream>
#include "clase.h"

using namespace std;
//---------------------------------------------------------------------------

int main(int argc, char* argv[])
{
DATOS datos;
DatosPersonales claseDatos;

cout << "Introduce el ID: ";
cin >> datos.id;

cout << "Introduce el nombre: ";
cin >> datos.nombre;

cout << "Introduce los apellidos: ";
cin >> datos.apellidos;

cout << "Introduce la edad: ";
cin >> datos.edad;

claseDatos.SetData(&datos);

memset(&datos,0,sizeof(DATOS));

claseDatos.GetData(&datos);
return 0;
}
//---------------------------------------------------------------------------

clase.cpp:
#include "clase.h"
#include <cstring>
//---------------------------------------------------------------------------

DatosPersonales::~DatosPersonales(){

}
//---------------------------------------------------------------------------

DatosPersonales::DatosPersonales(){

}
//---------------------------------------------------------------------------

//Metodos para obtener informacion
int DatosPersonales::GetId(){
return Datos.id;
}
//---------------------------------------------------------------------------

void DatosPersonales::GetName(char *name){
strncpy(name,Datos.nombre,SIZEMAXNAME);
}
//---------------------------------------------------------------------------

void DatosPersonales::GetSpells(char *spells){
strncpy(spells,Datos.apellidos,SIZEMAXSPELLS);
}
//---------------------------------------------------------------------------

int DatosPersonales::GetAge(){
return Datos.edad;
}
//---------------------------------------------------------------------------

void DatosPersonales::GetData(DATOS *data){
memcpy(data,Datos,sizeof(DATOS));
}
//---------------------------------------------------------------------------

//Metodos para enviar informacion
void DatosPersonales::SetId(int id){
Datos.id=id;
}
//---------------------------------------------------------------------------

void DatosPersonales::SetName(char *name){
strncpy(Datos.nombre,name,SIZEMAXNAME);
}
//---------------------------------------------------------------------------

void DatosPersonales::SetSpells(char *spells){
strncpy(Datos.apellidos,spells,SIZEMAXSPELLS);
}
//---------------------------------------------------------------------------

void DatosPersonales::SetAge(int age){
Datos.edad=age;
}
//---------------------------------------------------------------------------

void DatosPersonales::SetData(DATOS *data){
memcpy(Datos,data,sizeof(DATOS));
}
//---------------------------------------------------------------------------


clase.h:
#ifndef claseH
#define claseH
#define SIZEMAXNAME 20
#define SIZEMAXSPELLS 30

typedef struct{
int id;
char nombre[SIZEMAXNAME];
char apellidos[SIZEMAXSPELLS];
int edad;
}DATOS;

class DatosPersonales{
private:
DATOS Datos;
public:
~DatosPersonales();
DatosPersonales();

//Metodos para obtener informacion
int GetId();
void GetName(char *name);
void GetSpells(char *spells);
int GetAge();
void GetData(DATOS *data);

//Metodos para enviar informacion
void SetId(int id);
void SetName(char *name);
void SetSpells(char *spells);
void SetAge(int age);
void SetData(DATOS *data);
}
//---------------------------------------------------------------------------
#endif

Y aqui los errores que me salen:
[C++ Warning] main.cpp(5): W8058 Cannot create pre-compiled header: header incomplete
[C++ Error] main.cpp(5): E2040 Declaration terminated incorrectly
[C++ Error] main.cpp(13): E2451 Undefined symbol 'cout'
[C++ Error] main.cpp(14): E2451 Undefined symbol 'cin'
Al dar el primer error se me queda en la linea del "using namespace std" y si la comento se me queda en la siguiente.
¿Alguien sabria decirme que puede estar pasando?

ecfisa
06-12-2016, 16:12:17
Hola.

No probé si el código funciona correctamente o hace lo que debiera, pero para que compile sin error aplica las correcciones marcadas con: <<==.


Clase.h :

#ifndef claseH
#define claseH
#define SIZEMAXNAME 20
#define SIZEMAXSPELLS 30

typedef struct {
int id;
char nombre[SIZEMAXNAME];
char apellidos[SIZEMAXSPELLS];
int edad;
} DATOS;

class DatosPersonales {
private:
DATOS Datos;
public:
DatosPersonales();
~DatosPersonales();
//Metodos para obtener informacion
int GetId();
void GetName(char *name);
void GetSpells(char *spells);
int GetAge();
void GetData(DATOS *data);

//Metodos para enviar informacion
void SetId(int id);
void SetName(char *name);
void SetSpells(char *spells);
void SetAge(int age);
void SetData(DATOS *data);
}; // <<==

#endif


Clase.cpp:

#include "clase.h"
#include <string.h> // <<==

DatosPersonales::~DatosPersonales(){
}

DatosPersonales::DatosPersonales(){
}

//Metodos para obtener informacion
int DatosPersonales::GetId(){
return Datos.id;
}

void DatosPersonales::GetName(char *name){
strncpy(name, Datos.nombre, SIZEMAXNAME);
}

void DatosPersonales::GetSpells(char *spells){
strncpy(spells, Datos.apellidos, SIZEMAXSPELLS);
}

int DatosPersonales::GetAge(){
return Datos.edad;
}

void DatosPersonales::GetData(DATOS *data){
memcpy(data, &Datos, sizeof(DATOS)); // <<==
}

//Metodos para enviar informacion
void DatosPersonales::SetId(int id){
Datos.id = id;
}

void DatosPersonales::SetName(char *name){
strncpy(Datos.nombre, name, SIZEMAXNAME);
}

void DatosPersonales::SetSpells(char *spells){
strncpy(Datos.apellidos, spells, SIZEMAXSPELLS);
}

void DatosPersonales::SetAge(int age){
Datos.edad = age;
}

void DatosPersonales::SetData(DATOS *data){
memcpy( &Datos, data, sizeof(DATOS)); // <<==
}

Te adjunto el código corregido.

Saludos :)

aguml
06-12-2016, 16:48:51
Ok en cuanto pueda lo pruebo pero son los típicos fallos tontos que te vuelves loco y no ves jajaja.

aguml
06-12-2016, 16:54:34
Ya de paso hago otra consulta sobre lo que voy a añadir al código. La idea es usar fstream para leer y escribir en archivos de forma secuencial usando la estructura DATOS y eso lo hago sin problema en C pero nunca lo hice en C++ con ofstream y ifstream. Se como abrirlo de forma binaria usando ios::binary pero para leer y escribir, que yo sepa, los métodos read y write esperan char* y no se si es lo que tengo que usar ni como hacerlo. ¿Podéis explicarme esa parte solo?

ecfisa
06-12-2016, 17:37:35
Hola.

Un ejemplo (muy básico) que escribe y lee la estructura en un archivo:

#include <iostream>
#include <string.h>
#include <fstream>

using namespace std;

const int SIZEMAXNAME = 20;
const int SIZEMAXSPELLS = 30;
const char* FILENAME = "struct.dat";

struct Datos {
int id;
char nombre[SIZEMAXNAME];
char apellidos[SIZEMAXSPELLS];
int edad;
};

void saveStruct( Datos dt );
void readStruct( Datos& dt );

int main()
{
// unos datos en dt
Datos dt = { 1, "Pedro", "Diloretto", 28 };

// guardar en archivo
saveStruct( dt );

// limpiar struct
memset(&dt, 0, sizeof( dt ) );

// leer de archivo
readStruct( dt );

// mostrar
cout << dt.id << " " << dt.nombre << " " << dt.apellidos << " " << dt.edad;

cin.get();
return 0;
}

void saveStruct (Datos dt )
{
ofstream f_out( FILENAME, ios::binary );
f_out.write( reinterpret_cast<char*>( &dt ), sizeof( dt ) );
f_out.close();
}

void readStruct (Datos& dt )
{
ifstream f_in( FILENAME, ios::binary );
f_in.read( reinterpret_cast<char*>( &dt ), sizeof( dt ) );
f_in.close();
}


Saludos :)

aguml
06-12-2016, 18:56:50
¿Y que diferencia hay entre estos dos prototipos?
void readStruct (Datos* dt );
void readStruct (Datos& dt );
¿Con ambos podría conseguir lo mismo?
Si es así ¿por que usar uno en lugar de otro?

ecfisa
06-12-2016, 19:44:08
Hola.

Si, en C++ se puede conseguir lo mismo con ambos y, salvo algunos casos, se puede prescindir de las referencias. En C no existe el paso de parámetros por referencia (si bién se simula con punteros).

La referencia es como un alias o etiqueta de una variable por lo que deben inicializarse al declararlas,

int nro = 115;
int &ref_nro = nro;

int &ref; // no tiene sentido

mientras que el puntero es una variable que almacena una dirección de memoria.

¿ Por qué usar uno u otro en los parámetros ? creo que la ventaja mas notoria es mayor simpleza y legibilidad.
Puntero:

void inc(int* i, const int n)
{
*i += n;
}

int main()
{
int x = 5;

inc( &x, 5 );
cout << x ; // 10
...


Referencia:

void inc(int& i, const int n)
{
i += n;
}

int main()
{
int x = 5;

inc(x, 5);
cout << x; // 10
...

Buscando por los términos sin dudas hallaras mas detalles, como por ejemplo en este enlace: Parámetros por valor y por referencia (http://c.conclase.net/curso/?cap=015)

Saludos :)

aguml
06-12-2016, 20:51:18
Muchas gracias por las aclaraciones.