打开
ifstream从文件得到数据\ofstream向文件中写数据
此时要注意文件的编码方式与程序解码方式是否相同,特别是当文件中有中文字符时,中文字符一般占两个字节。
一般可设置为所有编码均可。
ifstream pbuy(filename);
locale loc = locale::global(locale(""));//设置为全部编码方式均可
pbuy.imbue(locale("", locale::all ^ locale::numeric)); //设置为全部编码方式均可
判断是否打开失败
if (!pbuy)
{ //打开文件失败
cerr<<"error: unable to open input file: "<<endl;
return -1;
}
注意,每一个打开后尽量都跟上这个
后缀汇总
ios::in打开一个供读取的文件(ifstream流的默认值)
ios::out打开一个供写入的文件(ofstream流的默认值)
ios::app在写之前找到文件尾
ios::ate打开文件后立即将文件定位在文件尾
ios::trunc废弃当前文件内容
ios::binary以二进制的形式打开一个文件,默认为文本文件
读取文件信息
读取整个文件信息https://blog.youkuaiyun.com/ljianhui/article/details/17386827
计算文件大小
pbuy.seekg(0, ios_base::end);//计算文件大小
int l = pbuy.tellg(); //计算文件大小
用read将文件储存在字符数组中
pbuy.seekg(0,ios_base::beg); //将文件储存在字符串中
char *text = new char[l+1];
pbuy.read(text, l);
……
delete [] text;
注意:将内容重新读入文件时,最后几个字符不输入,或将字符串最后字符设置为’\0’
text[l] = '\0';
或
for (int i = 0; i <= l - 3; i++)
ploginaccount2 << text[i];
修改文件中部分信息
先将文件所有信息储存在字符串中,再对字符串进行修改
增长或剪短时注意将字符数组整体移动,或在写入文件时使用if多输出或少输出。
查找文件中关键字来源于(https://blog.youkuaiyun.com/ljianhui/article/details/17386827)
int search(string guanjianzi,string filename) //查找filename文件中的guanjianzi字符串,并返回第一个字符的对于位置
{
ifstream pbuy(filename);
locale loc = locale::global(locale("")); //设置为全部编码方式均可
pbuy.imbue(locale("", locale::all ^ locale::numeric)); //设置为全部编码方式均可
if (!pbuy)
{ //打开文件失败
cerr<<"error: unable to open input file: "
<<filename<<endl;
return -1;
}
pbuy.seekg(0, ios_base::end); //计算文件大小
int l = pbuy.tellg(); //计算文件大小
pbuy.seekg(0, ios_base::beg); //将文件储存在字符串中
char *text = new char[l + 1]; //将文件储存在字符串中
pbuy.read(text, l); //将文件储存在字符串中
pbuy.close();
text[l] = '\0';
for (int i = 0; i <= (l - guanjianzi.length()); i++)
{
int j = 0;
while (j < guanjianzi.length() && text[i + j] == guanjianzi[j])
j++;
if (j == guanjianzi.length())
return i;
}
return -1;
}
移动读写指针位置此处来源于http://c.biancheng.net/view/309.html
ios::beg:让文件读指针(或写指针)指向从文件开始向后的 offset 字节处。offset 等于 0 即代表文件开头。在此情况下,offset 只能是非负数。
ios::cur:在此情况下,offset 为负数则表示将读指针(或写指针)从当前位置朝文件开头方向移动 offset 字节,为正数则表示将读指针(或写指针)从当前位置朝文件尾部移动 offset字节,为 0 则不移动。
ios::end:让文件读指针(或写指针)指向从文件结尾往前的 |offset|(offset 的绝对值)字节处。在此情况下,offset 只能是 0 或者负数。
在最后附上自己的代码(文本文件未上传)
#include <iostream>
#include<string>
#include<fstream>
#include <time.h>
#include<cstdlib>
using namespace std;
int search(string guanjianzi,string filename) //查找filename文件中的guanjianzi字符串,并返回第一个字符的对于位置
{
ifstream pbuy(filename);
locale loc = locale::global(locale("")); //设置为全部编码方式均可
pbuy.imbue(locale("", locale::all ^ locale::numeric)); //设置为全部编码方式均可
if (!pbuy)
{ //打开文件失败
cerr<<"error: unable to open input file: "
<<filename<<endl;
return -1;
}
pbuy.seekg(0, ios_base::end); //计算文件大小
int l = pbuy.tellg(); //计算文件大小
pbuy.seekg(0, ios_base::beg); //将文件储存在字符串中
char *text = new char[l + 1]; //将文件储存在字符串中
pbuy.read(text, l); //将文件储存在字符串中
pbuy.close();
text[l] = '\0';
for (int i = 0; i <= (l - guanjianzi.length()); i++)
{
int j = 0;
while (j < guanjianzi.length() && text[i + j] == guanjianzi[j])
j++;
if (j == guanjianzi.length())
return i;
}
return -1;
}
void time()
{
time_t time(time_t *calptr);//精确到秒
}
void modifybuy_money(float price,int number,string name)
{
ifstream pmoneyin("money.txt");
if (!pmoneyin)
{ //打开文件失败
cerr << "error: unable to open input file: "
<< "money.txt" << endl;
}
float money;
pmoneyin >> money;
pmoneyin.close();
money += price * number;
ofstream pmoneyout("money.txt", ios::trunc); //打开文件后清空文件
if (!pmoneyout)
{ //打开文件失败
cerr << "error: unable to open input file: "
<< "money.txt" << endl;
}
money = ((float)((int)((money + 0.05) * 10))) / 10;
string m = to_string(money);
pmoneyout << m;
pmoneyout.close();
ofstream pbuy;
pbuy.open("buy.txt", ios::app);
if (!pbuy)
{ //打开文件失败
cerr << "error: unable to open input file: "
<< "buy.txt" << endl;
}
struct tm pTm;
time_t now;
time(&now);
localtime_s(&pTm, &now); //获取时间
pbuy.seekp(0, ios::end);
string year = to_string(pTm.tm_year + 1900);//获取时间
pbuy << "\n" << year;
if ((pTm.tm_mon + 1) < 10)
pbuy << "0";
pbuy << (pTm.tm_mon + 1);
if (pTm.tm_mday < 10)
pbuy << "0";
pbuy << pTm.tm_mday;
if (pTm.tm_hour < 10)
pbuy << "0";
pbuy << pTm.tm_hour;
if (pTm.tm_min < 10)
pbuy << "0";
if (pTm.tm_min == 0)
pbuy << "0";
pbuy << pTm.tm_min;
if (pTm.tm_sec < 10)
pbuy << "0";
if (pTm.tm_sec == 0)
pbuy << "0";
pbuy << pTm.tm_sec
<< name
<< number
<< "+"
<< (price*number);
pbuy.close();
}
int modify_house(int house_num,int number,int location)
{
ifstream pbuy("warehouse.txt");
locale loc = locale::global(locale(""));
pbuy.imbue(locale("", locale::all ^ locale::numeric)); //设置为全部编码方式均可
if (!pbuy)
{ //打开文件失败
cerr << "error: unable to open input file: "
<< "warehouse.txt" << endl;
return -1;
}
pbuy.seekg(0, ios_base::end);
int l = pbuy.tellg();
pbuy.seekg(0, ios_base::beg);
char *text = new char[l + 1]; //将文件储存在字符串中
pbuy.read(text, l);
pbuy.close();
string house_num1 = to_string(house_num);
string house_num2 = to_string(house_num-number);
for (int i = 0; i < house_num2.size(); i++)
{
text[location + i ] = house_num2[i];
}
int flag_change = 0;
if (house_num1.size() != house_num2.size())
{
for (int k = location + house_num1.size() - 1; k < l; k++)
{
text[k] = text[k + 1];
}
flag_change = 1;
}
ofstream pbuy1("warehouse.txt", ios::trunc);
for(int i=0;i<l-3;i++)
pbuy1 << text[i];
if(!flag_change)
pbuy1 << text[l-3];
delete [] text;
return 0;
}
int modify_loginaccount( int loginaccount,int num)
{
string account = to_string(loginaccount);
int loc_loginaccount= search(account, "loginaccount.txt");
ifstream ploginaccount("loginaccount.txt");
locale loc = locale::global(locale(""));
ploginaccount.imbue(locale("", locale::all ^ locale::numeric));
if (!ploginaccount)
{ //打开文件失败
cerr << "error: unable to open input file: "
<< "loginaccount.txt" << endl;
return -1;
}
ploginaccount.seekg(0, ios_base::end);
int l = ploginaccount.tellg();
ploginaccount.seekg(0, ios_base::beg);
char *text = new char[l + 2];
ploginaccount.read(text, l);
int grade=0;
ploginaccount.close();
ifstream ploginaccount_("loginaccount.txt");
ploginaccount_.seekg(account.size() + 8 + loc_loginaccount, ios::beg);
ploginaccount_.imbue(locale("", locale::all ^ locale::numeric));
ploginaccount_ >> grade;
ploginaccount_.close();
string grade_s1 = to_string(grade);
int grade2= grade+ num;
cout << grade<<"%%%%*" << (int)('0') << grade2 << "%%%%"<< (int)(text[account.size() + 8 + loc_loginaccount - 1]);
string grade_s2 = to_string(grade2);
int flag_change = 0;
cout << account;
if (grade_s1.size() != grade_s2.size())//判断数字位数是否增加
{
for (int k = l; k > account.size() + 8 + loc_loginaccount - 1; k--)
{
text[k] = text[k-1];
}
flag_change = 1;
}
for (int i = 0; i < grade_s2.size(); i++)
text[account.size() + 8 + loc_loginaccount+i] = grade_s2[i];
ofstream ploginaccount2("loginaccount.txt", ios::trunc);
ploginaccount2.imbue(locale("", locale::all ^ locale::numeric));
for (int i = 0; i <= l - 3; i++)
ploginaccount2 << text[i];
if (flag_change)
ploginaccount2 << text[l - 2];
ploginaccount2.close();
return 1;
}
int identify_member(int member)
{
string m = to_string(member);
if (search(m, "member.txt")==-1)
return 0;
return 1;
}
int buy(int loginaccount) //输入用户账号
{
string name;
int number;
int member=1;
float discount=1;
cout << "\n\n\n\t\t\t欢迎来到北邮超市购物\n";
cout << "\n\t\t请问有会员卡吗?有请输入会员卡卡号,没有请按0 ";
while (member)
{
cin >> member;
if (!member)
break;
if (!identify_member(member))
{
cout << "\n\t\t抱歉,您的会员卡号错误,请重新输入,没有请按0 ";
}
else
{
cout << "\n\t\t您的会员卡号有效,本次购物您可以享受九折优惠";
discount = 0.9;
break;
}
}
getchar();
cout << "请按回车键继续";
getchar();
system("cls");
int flag_buy = 1;
while (flag_buy)
{
cout << "\n\t\t\t请输入所购买的物品名称:";
cin >> name;
cout << "\n\t\t\t请输入该物品数量:";
cin >> number;
int location = search(name, "warehouse.txt");
if (location == -1)
{
cout << "\n\t\t抱歉,本店没有您需要的商品";
cout << "\n\t\t请问您要继续购物吗,继续请按1,退出请按0";
cin >> flag_buy;
continue;
}
ifstream housein("warehouse.txt");
if (!housein)
{ //打开文件失败
cerr << "error: unable to open input file: "
<< "warehouse.txt" << endl;
}
housein.seekg(location + name.length(), ios::beg);
int price;
housein >> price;
string string_price = to_string(price);
housein.seekg(location + name.length(), ios::beg);
housein.seekg(string_price.size(), ios::cur);
int house_num;
housein >> house_num;
housein.close();
if (house_num - number < 0)
{
cout << "\n\t\t抱歉,您需要的物品没有库存";
cout << "\n\t\t请问您要继续购物吗,继续请按1,退出请按0: ";
cin >> flag_buy;
continue;
}
modify_loginaccount(loginaccount, number); //调整登陆账户使用次数
modifybuy_money(price*discount, number, name); //调整buy文件和money文件
string price1 = to_string(price);
modify_house(house_num, number, location + name.length() + price1.size() + 1);//调整库存
cout << "\n\t\t请问您要继续购物吗,继续请按1,退出请按0: ";
cin >> flag_buy;
}
return 1;
}
int main()
{
buy(2019212019);//传登录账户
}