文件写入的问题
我编写了一个ATM机的模拟程序,运行程序,先从存有账户记录的文件中读取所有的账户信息,并用一个容器存储记录。当用户修改密码或提款时,修改相应的账户信息,并用新的信息覆盖掉该账户原有的信息。下面的函数实现此功能:首先,读取旧文件的账户信息,根据账户的账号依次查找对应的账户信息。一旦找到,就把新的账户信息写入对应的行。
账户信息的文件格式是:
134671 zhangsan 12356.42 134671$
158231 lisi 12356.42 158231$
181791 wangwu 12356.42 181791$
一行存储一个账户信息:账号 姓名 余额 密码$
用空格作为账户信息内部的分隔符,用$作为一条信息的终至符。
void Atm::UpdateAccountFile()
{
size_t count = 0;
double balance;
string accountList;
string strTemp;
Account AccountTemp;
size_t positionPre = 0;
size_t positionPost = 0;
size_t accountListCount = 0;
fstream inOut;
inOut.open(m_accountFile.c_str(), fstream::in | fstream::out);
while (getline(inOut, accountList))//读取一行记录
{
accountListCount = accountList.size();
positionPost = accountList.find_first_of( "$ ", positionPre);//确定$所在位置
strTemp = accountList.substr(positionPre, positionPost);//剥离出账户信息字符串
accountList = strTemp;
positionPost = accountList.find_first_of( " ", positionPre);//获得第一个空格所在位置
strTemp = accountList.substr(positionPre, (positionPost - positionPre));//获得账户的账号
if (m_accountVec[m_index].GetNumber() == strTemp)//如果此账号是需要重新写入的账号
{
inOut.seekg(0 - accountListCount - 2, ios::cur);//重定位文件指针为行首
inOut < < m_accountVec[m_index].GetNumber() < < ' '
< <m_accountVec[m_index].GetName() < < ' '
< < GetStrFromNum(balance) < < ' '
< < m_accountVec[m_index].GetPassword() < < '$ ';//写入新的账户信息
count = (m_accountVec[m_index].GetNumber()).size() +
(m_accountVec[m_index].GetName()).size() +
(m_accountVec[m_index].GetPassword()).size() +
(GetStrFromNum(balance)).size() + 3 + 1;//新的账户信息的字符串长度
if (count < accountListCount)//如果修改后的账户信息字符串长度小于修改前长度,则进行如下操作:用 '\0 '填充,并以 '\n '结束。
{
count = accountListCount - count;
while (count != 0)
{
inOut < < '\0 ';
--count;
}
inOut < < '\n ';
}
}
accountListCount = 0;
}
}
ATM类:
class Atm
{
public:
Atm(size_t cash, const string &accountFile)
:m_cashInAtm(cash), m_accountFile(accountFile
{
GetAccountVec(m_accountFile);
}
Atm(const Atm ©Atm)
{
m_cashInAtm = copyAtm.m_cashInAtm;
m_accountVec = copyAtm.m_accountVec;
m_accountFile = copyAtm.m_accountFile;
}
Atm(){}
string GetStrFromNum(long double value);
int CharToInt(const char &intChar);
double StrToBalance(const string&);
void Welcome();
bool CheckPassword(const string&);
bool CheckNumber(const string&);
void ChangePS(Account &account);
void FetchCash(Account &account);
void SaveMoney(Account &account);
void DispInformation(Account &account);
void Service(Account &account);
void PrintWarrant(Account &account, const size_t &cash);
void NeedOtherServ(Account &account);
void Lock();
void BackToMenu(Account &account);
void Exit();
void Wait();
void GetAccountVec(const string &accountFile);
void UpdateAccountFile();
private:
string m_accountFile;
string m_passwordToUnlock;
size_t m_cashInAtm;
size_t m_index;
vector <Account> m_accountVec;
};
但上面的函数并不能实现相应的功能。重新写入账户信息时,会出现许多莫名其妙的错误。请各位大虾帮忙看看。
[解决办法]
我建议你每次都重建整个文件。
[解决办法]
你遇到的问题我也曾经遇到过,存储的信息也是具体的字符串,可是这样的存储以后,每一行的内容就已经确定了,如果在你重新写入的情况下,长度小于原有的长度,那么就不能完全覆盖,使信息紊乱,如果长度比原有的信息长,那么就会覆盖掉下一行的一部分信息,打破了现在的格式,使信息读入错误.
我的解决方法就是存储对象,将每个对象存储在文件当中,在文件处理的情况下,一次性的读入大量的对象,然后进行处理,最后存储的时候再次打开文件,将内部的信息全部清除掉,然后重新写入所有的信息.
优点:(1).只需要一次读盘和写盘,减少了硬件之间的交互,从而减少了时间的浪费.
(2).将信息通过变量管理的方式存储在内存当中,加快了程序运行的速度.
(3).保证了信息的完整性与安全性,将文件以乱码的形式存储,减少了不必要的篡改.
(4).信息的修改,删除等操作只是对变量内容的修改和删除,方便了大量的操作.
...
缺点: 需要大量的内存来存储文件信息(整个的文件信息).