我对二进制文件有一个相当困难的问题。我被要求制作一个程序,将信息存储在文件中,但是在顺序模式下。由于我不允许直接在顺序模式下修改内容,因此我创建了一个函数,它首先读取文件,直到找到正确的注册表,同时将其他注册表复制到辅助文件中。当我完成修改我需要的东西时,我将其复制到辅助文件并继续复制。完成后,我将所有内容从辅助文件复制到原始文件。我已经做了以下各种二进制文件的例子,但我的程序做了一些奇怪的事情。它开始吃掉我写的所有信息,只留下最后一个条目(类似无限截断的东西),更糟糕的是,有一部分(标记为“讨厌的部分”)开始一个没有意义的无限循环(它是好像文件有无限大小)我已经把这个逻辑变成了一千次,我似乎没有发现任何错误,我不知道你是否可以帮助我,如果我错过了一些重要的东西。
以下是我正在使用的课程
class Cliente{
public:
int numCuenta;
char dni[10];
char nombre[40];
};
class Cuenta{
private:
int numCuenta;
double monto;
int numDuenhos;
public:
const static double MONTO_MIN = 100.0;
Cuenta(){
numCuenta = 0;
monto = 0;
numDuenhos = 0;
}
int getnumCuenta(){
return numCuenta;
}
void setnumCuenta(int numCuenta){
this->numCuenta= numCuenta;
}
int getnumDuenhos(){
return numDuenhos;
}
void setnumDuenhos(int numDuenhos){
this->numDuenhos= numDuenhos;
}
double getMonto(){
return monto;
}
void setMonto(double monto){
this->monto = monto;
}
};
和有问题的功能
void modificarCuenta() {
Cuenta aux;
Cliente c;
ifstream rep_cuentas("cuentas.bin");
ofstream buf_cuentas("cuentas_rep.bin",ios::out | ios::trunc | ios::binary);
if(!rep_cuentas) {
cout <<endl << "Error al leer fila principal";
}
else if(!buf_cuentas) {
cout << endl << "Error al abrir el archivo buffer";
}
else {
cout <<endl << "Ingrese el numero de cuenta a modificar: "; //id of entry
int num_cuenta;
cin >> num_cuenta;
ifstream rep_clientes("clientes.bin");
ofstream buf_clientes("cilentes_rep.bin",ios::out | ios::trunc | ios::binary);
//este archivo es necesario, por eso termina si no lo lee
if (!rep_clientes) {
cerr << "Error al Abrir el Archivo de Clientes" << endl;
return;
}
rep_cuentas.read(reinterpret_cast<char *>(&aux),sizeof(Cuenta));
while(!rep_cuentas.eof()){
if(aux.getnumCuenta() == num_cuenta){
rep_clientes.read(reinterpret_cast<char *>(&c),sizeof(Cliente));
while(!rep_clientes.eof()){
if(c.numCuenta == num_cuenta){
cout << "DNI del Cliente: " << c.dni << endl; //old dni
cout << "Nombre del Cliente: " << c.nombre << endl; // old name
cout << "Modificar estos datos? (1 para confirmar): ";
int opc;
cin >> opc;
if (opc == 1){
c.numCuenta = aux.getnumCuenta();
cout << endl << "Ingrese nuevo DNI: "; //new dni
cin >> c.dni;
cout << endl << "Ingrese nuevo Nombre: "; //new name
cin >> c.nombre;
}
}
buf_clientes.write(reinterpret_cast<char *>(&c),sizeof(Cliente));
rep_clientes.read(reinterpret_cast<char *>(&c),sizeof(Cliente));
}
int num = aux.getnumDuenhos();
while(true){
cout << endl << "Desea ingresar mas duenhos? (1 para confirmar): "; //appending new user?
int op;
cin >> op;
if (op == 1){
c.numCuenta = aux.getnumCuenta();
cout << endl << "Ingrese nuevo DNI: "; //new dni
cin >> c.dni;
cout << endl << "Ingrese nuevo Nombre: "; //new name
cin >> c.nombre;
num++;
buf_clientes.write(reinterpret_cast<char *>(&c),sizeof(Cliente));
}
else{
aux.setnumDuenhos(num);
break;
}
}
}
buf_cuentas.write(reinterpret_cast<char *>(&aux),sizeof(Cuenta));
rep_cuentas.read(reinterpret_cast<char *>(&aux),sizeof(Cuenta));
}
rep_clientes.close();
buf_clientes.close();
}
rep_cuentas.close();
buf_cuentas.close();
ofstream rcuentas("cuentas.bin",ios::out | ios::trunc| ios::binary);
ifstream bcuentas("cuentas_rep.bin");
if(!rcuentas) {
cout << endl << "Error al abrir la fila principal";
}
else if(!bcuentas) {
cout << endl << "Error al abrir el archivo buffer";
}
else{
bcuentas.read(reinterpret_cast<char *>(&aux),sizeof(Cuenta));
while(!bcuentas.eof()){
rcuentas.write(reinterpret_cast<char *>(&aux),sizeof(Cuenta));
bcuentas.read(reinterpret_cast<char *>(&aux),sizeof(Cuenta));
}
rcuentas.close();
bcuentas.close();
ofstream rclientes("clientes.bin",ios::out | ios::trunc | ios::binary);
ifstream bclientes("clientes_rep.bin");
bclientes.read(reinterpret_cast<char *>(&c),sizeof(Cliente));
//pesky part
while(!bclientes.eof()){
rclientes.write(reinterpret_cast<char *>(&c),sizeof(Cliente));
bclientes.read(reinterpret_cast<char *>(&c),sizeof(Cliente));
}
//end of pesky part
bclientes.close();
rclientes.close();
cout << endl << "Modificacion Realizada con Exito" << endl; //confirmation text
}
}
如果你需要它,这是写一个新条目的功能,它完全正常:
void crearCuenta(){
Cuenta aux;
aux.setnumCuenta(0);
ifstream rcuentas("cuentas.bin");
if(!rcuentas){
cout<< endl <<"Primer uso del Sistema detectado, generando numero de cuenta inicial" <<endl;
}
else {
rcuentas.read(reinterpret_cast<char *>(&aux),sizeof(Cuenta));
while(!rcuentas.eof()){
rcuentas.read(reinterpret_cast<char *>(&aux),sizeof(Cuenta));
}
rcuentas.close();
}
Cuenta cu;
cu.setnumCuenta(aux.getnumCuenta() + 1);
int num_duenhos = 0;
ofstream a_clientes("clientes.bin",ios::app |ios::binary);
while(true){
char dni[10];
cout << "Ingrese el DNI del Duenho: "; //new dni
Cliente c;
cin >> c.dni;
cout << "Ingrese el Nombre del Duenho: "; //new name
cin >> c.nombre;
c.numCuenta = cu.getnumCuenta();
num_duenhos++;
a_clientes.write(reinterpret_cast<char *>(&c),sizeof(Cliente));
cout << "Desea ingresar otro duenho? (escriba 1 para confirmar): "; //another entry?
int val;
cin >> val;
if (val != 1)
break;
}
cu.setnumDuenhos(num_duenhos);
while(true){
double monto;
cout << endl;
cout << "Ingrese el monto con el cual iniciara la cuenta:"; //numerical value (greater than 100)
cin >> monto;
if (monto < Cuenta:: MONTO_MIN){
cout << "Debe ingresar un valor mayor a " << Cuenta::MONTO_MIN << endl;
}
else{
cu.setMonto(monto - monto * 0.005);
break;
}
}
ofstream acuentas("cuentas.bin",ios::app| ios::binary);
if(!acuentas){
cout<< endl <<"ERROR en la fila secuencial" <<endl;
}
else{
acuentas.write(reinterpret_cast<char *>(&cu),sizeof(Cuenta));
acuentas.close();
}
cout << "Cuenta Guardada Satisfactoriamente con número: " << cu.getnumCuenta() << endl; //confirmation text
}
不介意西班牙语文本,它只是用于用户交流。任何帮助将受到高度赞赏
答案 0 :(得分:2)
对于初学者,你不是以二进制模式打开输入,所以除非 你在Unix下,你不会在磁盘上看到文件的字节图像。 如果我理解正确,您希望阅读您的文件 用同一个程序写的;如果是这样,阅读和写作不同 模式不起作用。
其次,您正在阅读和编写复杂的数据结构(Cuenta
,
Cliente
}使用istream::read
和ostream::write
。事实并非如此
工作,除了少数情况。无论是二进制还是文本,所有文件
有一种格式,这种格式必须在代码中得到尊重。您的
类是POD,或者足够接近一个,你可能不会
在您的开发中进行一些更改之前,请先查看问题
环境,但它仍然存在。 (事实上你需要一个
reinterpret_cast
这样做应该是一个红旗。)它绝对不会起作用
(在Unix下除外)如果您以文本模式读取或写入。读一个文件
以这种方式在文本模式下写入将返回其他字符,或停止
在文件结束之前,在Windows下。
此外,while ( file.eof() )
是读取文件的正确方法。该
file.eof()
的结果在输入之后才是可靠的
失败。对于文本文件,通常使用:
while ( file >> something ) ...
或
while ( std::getline( file, line ) ) ...
像你一样阅读,
while ( rep_clentes.read(...) ) ...
如果您解决了其他问题,应该可行。
这可能是你无限循环的原因; istream
在。{
由于某种原因而不是文件结尾的错误状态,因此eof()
会
永远不会成真。