c++中的Fstream覆盖,即使使用ios::app
Fstream overwriting in C++ even with ios::app
我有一个问题。我启动了一个程序,可以保存数据(姓名、姓氏等),并将它们保存到一个txt文件中。问题是它覆盖了文件中的数据。我已经在fstream文件中写了ios::app,但没有任何区别。
你们能帮帮我吗?
我想给你代码,但它是西班牙语的,所以我想我帮不了你。
提前感谢;)
#include <iostream>
#include <windows.h>
#include <fstream>
#include <string.h>
using namespace std;
const int salario_minimo = 550;
fstream userdata;
int i;
struct FUNCIONARIO{
char horario;
char categria;
int salario_inicial;
string nombre;
string apellido;
int id;
int salario_final;
};
FUNCIONARIO func[18];
int empleados;
int op;
int registrar(){
userdata.open("FUNCIONARIOS.txt");
cout << "Escriba el nombre del nuevo funcionario" << endl;
cin >> func[empleados].nombre;
cout <<"Escriba el apellido del nuevo funcionario"<<endl;
cin >> func[empleados].apellido;
cout<< "Especifique su puesto -Operario(O) o Gerente(G)"<<endl;
cin >> func[empleados].categria;
cout << "Especifique su horario -Manana(M), tarde(T) o noche(N)"<<endl;
cin >> func[empleados].horario;
i = empleados;
empleados++;
for(int o = 0; o < 18; o++){
int p = o++;
userdata << i << endl << empleados << endl << func[o].nombre << endl
<< func[o].apellido << endl << func[o].categria << endl
<< func[o].horario << endl << func[o].salario_inicial << endl
<< func[o].salario_final << endl;
userdata.close();
}//RESOLVER OVERWRITING URGENTE!!!!!
cout << "EMPLEADO NUMERO: " << empleados << endl;
cout << "NOMBRE: " << func[i].nombre << endl;
cout << "Apellido: " << func[i].apellido << endl;
cout << "EMPLEO: ";
switch (func[i].categria){
case 'G': cout << "GERENTE" << endl; break;
case 'O': cout << "OPERARIO" << endl; break;
default: break;
}
cout << "HORARIO: ";
switch(func[i].horario){
case 'M':
cout << "MANANA" << endl;
break;
case 'T':
cout << "TARDE" << endl;
break;
case 'N':
cout << "NOCHE" << endl;
break;
default:
break;
}
cout << "SALARIO INICIAL: " <<func[i].salario_inicial << endl;
cout << "SALARIO FINAL: " <<func[i].salario_final << endl;
system("PAUSE");
return 0;
}
int main(){
ifstream comprobador;
comprobador.open("FUNCIONARIOS.txt");
if (comprobador.fail()){
cout << "FILE NOT FOUND" << endl;
userdata.open("FUNCIONARIOS.txt", fstream::in | fstream::out | ios_base::app);
empleados = 0;
}else{
userdata.open("FUNCIONARIOS.txt",fstream::in | fstream::out | ios_base::app);
userdata >> i >> empleados;
userdata.close();
}
cout << "Numero Actual De Empleados:" << empleados << endl;
cout << "Bienvenido a BUSINESS MANAGEMENT SOFTWARE 1.0n Por favor, seleccione una de estas opciones" << endl;
cout << "1.Registrar Un Nuevo Funcionarion2.Ver Hojas De Pagon3.Salir" << endl;
cin >> op;
switch (op){
case (1):
registrar();
break;
/*case 2:
mostrar();
break;*/
default:
cerr << "Please, Choose A Valid Option" << endl;
main();
break;
}
userdata.close();
return 0;
}
您的代码中可能存在各种错误。我会尽量强调其中最重要的几点。
局部变量优于全局变量
i
, userdata
, empleados
或op
不需要是全局的。这是c++,不是C,作用域非常重要。在这种情况下,不需要在fstream
上调用close
。
不要递归地调用main
这不是错误的,也不是危险的,但这肯定是不好的做法。main方法应该从运行时调用,并且应该只调用一次。同样,这里也不需要递归,完全没有必要。只要写一个无限循环,并使用continue
或break
/return
跳出它。
的例子:
while (true) {
int op = 0;
cin >> op;
switch (op) {
case 1:
registrar();
return 0; // Note that break would only break switch, not the while-loop
default:
cerr << "Please, Choose A Valid Option" << endl;
continue;
}
}
在for循环中调用close
这个循环应该如何工作?它在第一次迭代后关闭userdata
,然后再尝试向文件中写入17次(由于文件已关闭,因此将失败):
for(int o = 0; o < 18; o++){
int p = o++;
userdata << /* ... */ endl;
userdata.close();
}//RESOLVER OVERWRITING URGENTE!!!!!
为什么文件被覆盖
可以在多个位置打开文件,但只有两种情况下指定app
。看一下这部分代码,注意注释:
ifstream comprobador;
comprobador.open("FUNCIONARIOS.txt"); // Open the file for input, no app
if (comprobador.fail()){
cout << "FILE NOT FOUND" << endl;
// Ok, file not found, open with append (no need here, it's empty anyway!)
userdata.open("FUNCIONARIOS.txt", fstream::in | fstream::out | ios_base::app);
empleados = 0;
}else{
// File already found and still open for input, reopen with new fstream
// and specify append
userdata.open("FUNCIONARIOS.txt",fstream::in | fstream::out | ios_base::app);
// app places the filecursor at the end, the next statement will not work!
userdata >> i >> empleados;
// Now you close the file again!
userdata.close();
}
所以基本上在第一种情况下,文件是空的并打开的,在第二种情况下,文件刚刚打开但随后关闭。这不是很好,if
应该使userdata
处于一致状态。现在假设文件是关闭的(else
-statement),您调用registrar
。registrar
的第一行是这样的语句:
userdata.open("FUNCIONARIOS.txt");
再次打开文件,这次没有指定app
。
我建议打开文件一次在您的程序中使用ifstream
作为输入,读取所有条目(如果有的话)到内存中,添加新条目,然后使用ofstream
与ios::trunc
指定写入文件一次,重写所有条目到文件,或者使用ofstream
与ios::app
指定打开文件,只添加一个条目。您必须首先解析整个文件,因为您需要最后一行的empleados
的编号。如果在{ ... }
范围内打开文件,它将在结束时关闭自己,不需要调用close。如果使用指定的文件名和标志直接构造fstream,也不需要调用open
。一个例子:
void registrar() {
// ...
ofstream file("FUNCIONARIOS.txt", ios::app);
if (file) {
file << /* ... */ endl;
}
} // file will be closed here because ofstreams destructor is called
- 使用ios:ate写入到流会覆盖现有文件
- 如何访问RTCVideoRenderer的帧?(ios)
- ios::fmtflags 在 C++ 中是如何工作的?setf() 是如何工作的?
- 我可以在 iOS 或 mac 应用程序中使用C++代码吗?
- "string.h"在构建适用于iOS的qt应用程序中找不到消息
- 为什么 C++ 11 在 ios 类中添加了运算符 bool
- 文件模式标志"ios::app"是否用于删除文件(如果文件已存在)?
- ios::app 和 ios::noreplace 模式在文件处理中有什么区别?
- c++ 中的 ios::app、out 和 trunc 有什么区别?
- ios::app和ios::ate之间有什么区别
- ios::app 和用于输入的 fstream 之间的交互
- C++:ios:app在fstream中不需要ios:out
- 为什么tellp()对ios:app返回0,而对ios:ate不返回
- 如何在c++中使用seekg和seekp附加到文件,而不使用ios:app标志
- ios::app 模式和 fstream::write 是否在某种程度上彼此不兼容
- ios::app 不也暗示 ios::out 在C++
- 为什么ios::app(append)在C++中不起作用
- 为什么ofstream( "log.txt" , ios::app|ios::trunc);总是失败?
- 文件处理C++,在ios::app模式下打开,文件被擦除
- c++中的Fstream覆盖,即使使用ios::app