1.创建一个顺序文件与文件输入(追加)
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
int main()
{
ofstream file; //注意是ofstream而不是ifstream,二者不同,见下
file.open("1.txt", ios::out);//ios::app表示追加;ios::ate可以在文件的任何位置写数据;ios::in表示输入(但是此时文件必须是存在的,而且输入的回逐一替换以前的,但是不会一次性将以前的全部删除);ios::out表示输出(但是会删除已有内容)
if (!file)
{
cerr << "File Open Error !" << endl;
exit(1);
}
cout << "input the account,name,and balance" << endl;
int account;
string name;
double balance;
//当一个指针作为判定条件时,C++将一个空指针视为FALSE,非空为TRUE,这里隐式的调用了cin成员运算符void*;
while (cin >> account >> name >> balance)
{
file << account << ' ' << name << ' ' << balance << endl;
}//最终输入control+Z终止
file.close();//当不需要时 可以显示的调用该函数来减少资源占用
}
2.从顺序文件中读取数据
#include<iostream>
#include<fstream>
#include<string>
#include<iomanip>
using namespace std;
void Print(int account, const string name, double balance)
{
cout << left << setw(10) << account << setw(13) << name << setw(13) << balance << endl;
}
int main()
{
ifstream file("1.txt", ios::in);
if (!file)
{
cerr << "file open error !" << endl;
exit(1);
}
cout << left << setw(10) << "Account" << setw(13) << "Name" << setw(13) << "Balance" << /*fixed << showpoint <<*/ endl;
int account;
string name;
double balance;
while (file >> account >> name >> balance)
{
Print(account, name, balance);
}
return 0;
}
重定位文件定位指针,istream和ostream都提供了成员函数来重定位文件定位指针(文件中下一个被读取或写入的字节号);在istream中,这个成员函数为seekg(),在ostream中为seekp();每个istream对象都有一个读取指针来指出文件中下一个输入的字节号,每个ostream对象都有一个写入指针来指出文件中下一个被输出的字节号;如:file.seekg(0)将定位指针重定位于文件的起始位置,其中还可以指定第二个参数来指定寻找的方向,可以是ios::beg(默认)(相对于流的开始位置进行定位);ios::end(相对于文件的末尾);ios::cur(相对于文件的当前位置)(注意数值代表的是文件开始位置到当前位置的字节数);如:file.seekg(n,ios::cur)
同样的操作可以使用osream中的seekp来实现;
成员函数tellg和tellp分别用于返回当前的“读取”和“写入”指针的位置
3.更新顺序文件:如果要将300 White 0.00数据替换成300 Worthington 0.00 的话,由于Worthington比White多了六个字符,则从“o”之后的字符就会覆盖文件中下一条顺序记录的开头;如果要使用这种方法来更新数据的话就只有用两个文件,先将该数据之前的数据拷贝到新文件中,让后再替换,之后再拷贝该数据之后的数据过去即可
实例:反复读取文件
#include<iostream>
#include<fstream>
#include<iomanip>
#include<string>
#include<stdlib.h>
using namespace std;
enum RequestType {ZERO_BALANCE = 1,CREDIT_BALANCE,DEBIT_BALANCE,END};
int getRequest();
bool shouldDisplay(int, double);
void outputLine(int, const string, double);
int main()
{
//cout << ZERO_BALANCE << " " << CREDIT_BALANCE << " " << DEBIT_BALANCE << " " << END << endl;
ifstream inClientFile("1.txt", ios::in);
if (!inClientFile)
{
cerr << "File Opened Erro !" << endl;
exit(1);
}
int request;
int account;
string name;
double balance;
request = getRequest();
while (request != END)
{
switch (request)
{
case ZERO_BALANCE:
cout << " Accounts With Zero Balance : ";
break;
case CREDIT_BALANCE:
cout << " Accounts With Credit Balance : ";
break;
case DEBIT_BALANCE:
cout << " Accouts With Debit Balance : ";
break;
}
inClientFile >> account >> name >> balance;
while (!inClientFile.eof()) //返回一个零值,直到文件结束
{
if (shouldDisplay(request,balance))
{
outputLine(account, name, balance);
}
inClientFile >> account >> name >> balance;
}
inClientFile.clear();
inClientFile.seekg(0);
request = getRequest();
}
cout << "End Of Run !" << endl;
return 0;
}
int getRequest()
{
int request;
cout << " Enter The Request : "
<< "1-List Accounts Of Zero Balance "
<< "2-List Accounts Of Credit Balance "
<< "3-List Accounts Of Debit Balance "
<< "4-End Of Run !" << endl;
do
{
cout << " ?";
cin >> request;
} while (request<ZERO_BALANCE && request>END); //这里的条件不成立,所以只允许输入一次
return request;
}
bool shouldDisplay(int type, double balance)
{
if (type == ZERO_BALANCE && balance == 0)
return true;
if (type == CREDIT_BALANCE &&balance < 0)
return true;
if (type == DEBIT_BALANCE && balance >0)
return true;
return false;
}
void outputLine(int account, const string name, double balance)
{
cout << left << setw(10) << account << setw(13) << name << setw(13) << balance << endl;
}
4.随机存取文件:
(a):创建随机存取文件
(1)ostream的成员函数write()函数可以从指定位置写入数据;istream中的read()函数可以从指定位置读取字节数据。
(2)write函数使用:file.write(reinterpret_cast<const char *>(&number),sizeof(number)) //实际上reinterpret_cast为强制类型转换,这里write函数要求const char * 类型;但是reinterpret_cast与编译器相关,所以尽量不要使用
对于read函数:file.read(reinterpret_cast<char *>(&number),sizeof(number)),要求char*类型的数据
(3)调用string类的函数将一个string数据写入到定长的char数组中(这也是为了创建随机存取文件),实例:
string lastNameString;
char lastName[15];
int length = lastNameString.size();
lastNameString.copy(lastName, length);
lastName[length] = ' '; //记住最后还要自己加
(4)ofstream outFile("1.txt", ios::out | ios::binary); //ios::binary表示以二进制形式打开文件,如果要写入定长的记录,这是比要的
(5)对于既要读又要写的文件,课可以直接使用(fstream)
ifstream File("1.txt", ios::in | ios::out | ios::binary);
(6)file.clear()//表示复位文件结束指示符,一般在文件读取错误或者用户输入错误时,又要继续使用文件,此时应该调用此函数