c++文件操作
一、文件打开选项设置
ios::in = 0x01, //供读,文件不存在则创建(ifstream默认的打开方 式)
ios::out = 0x02, //供写,文件不存在则创 建,若文件已存在则清空原内容(ofstream默认的打开方式)
ios::ate = 0x04, //文件打开时,指针在文件最后。可改变指针的位置,常和in、out联合使用
ios::app = 0x08, //供写,文件不存在则创建,若文件已存在则在原文件内容后写入 新的内容,指针位置总在最后
ios::trunc = 0x10, // 在读写前先将文件长度截断为0(默认)
ios::nocreate = 0x20, //文件不存在时产生错误,常和in或app联合使用
ios::noreplace = 0x40, //文件存在时产生错误,常和out联合使用
ios::binary = 0x80 //二进制格式文件
二、fstream
库主要包括以下几个类:
std::ifstream
:用于从文件读取数据的输入文件流类。std::ofstream
:用于向文件写入数据的输出文件流类。std::fstream
:用于同时进行文件的读取和写入操作的输入/输出文件流类。
注意事项:
若字符串使用了string
定义,请在打开时将其转化为const char*
类型,这是因为在C语言中并没有string
类型,所有IO均采用char
类型,建议定义字符串时使用char
以下是 fstream 的一些使用方法
打开文件:
-
ifstream file(“filename.txt”)
:创建一个ifstream
对象并打开名为filename.txt
的文件以进行读取。 -
ofstream file(“filename.txt”)
:创建一个ofstream
对象并打开名为filename.txt
的文件以进行写入。 -
fstream file(“filename.txt”)
:创建一个fstream
对象并打开名为filename.txt
的文件以进行读取和写入。 -
你也可以使用先创建的形式,再通过open函数创建具体的文件 ,例如:
#include<iostream> #include<fstream> using namespace std; int main() { fstream IoFile; IoFile.open("./a.bat",ios_base::out); //模式选择 }
关闭文件:
file.close()
:关闭与文件流关联的文件。
检查文件是否打开成功:
file.is_open()
,为true则打开成功,反之未成功。
从文件读取数据:
file>>variable
:从文件流中读取数据并存储到变量中。getline(file, line)
:从文件流中读取一整行数据并存储到line
字符串中。
向文件写入数据:
file << data
:将数据写入到文件流中。
检查文件流状态:
file.eof()
:检查文件流是否已到达文件末尾,true
则是到达,反之。file.fail()
:检查文件流是否发生错误,出现错误则返回true
。file.good()
:检查文件流是否处于良好状态,发生错误则为true
。
演示代码:
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
fstream IoFile;
IoFile.open("./a.bat",ios::out); //模式选择
IoFile<<"张三"<< " " << 76 << " " << 98 << " " << 67 << endl;
IoFile << "李四"<< " " << 89 << " " << 70 << " " << 60 << endl;
IoFile << "王十"<< " " << 91 << " " << 88 << " " << 77 << endl;
IoFile << "黄二"<< " " << 62 << " " << 81 << " " << 75 << endl;
IoFile << "刘六"<< " " << 90 << " " << 78 << " " << 67 << endl;
IoFile.close(); //先写入
IoFile.open("./a.bat",ios::in|ios::binary); //二进制读
char name[10];
int chinese,math,english;
cout<< "姓名\t"
<< "英语\t"
<< "数学\t"
<< "英语\t"
<< "总分" << endl;
// cout<<IoFile.is_open()<<endl;
while(IoFile.is_open()&&!IoFile.eof()){
IoFile>>name;
IoFile>>chinese>>math>>english;
cout << name << "\t" << chinese << "\t" << math << "\t" << english << "\t"
<< chinese + math + english<< endl;
}
IoFile.close();
return 0;
}
使用ofsteam
与ifstream
的例题
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
char ch;
ofstream out;
out.open("./test.bat",ios::out|ios::binary);
for(int i=0;i<90;i++)
{
if(i>0&&i%30==0){
out.put('\n');
}
out.put(i);
out.put(' ');
}
out.close();
ifstream in("./test.bat",ios::in|ios::binary);
cout<<"是否打开文件成功:"<<in.is_open()<<endl;
while(in.get(ch))
{
cout<<ch;
}
in.close();
return 0;
}
读写二进制文件:
首先你要注意我们不再使用插入和提取操作符(译者注:<< 和 >> 操作符). 你可以这么做,但它不会用二进制方式读写。你必须使用read() 和write() 方法读取和写入二进制文件,例如:
ofstream fout("file.dat", ios::binary);
这会以二进制方式打开文件, 而不是默认的ASCII模式。
二进制写入:
fout.write((char *)(&number), sizeof(number));
二进制文件最好的地方是可以在一行把一个结构写入文件,用ASCII文件,你不得不每次一条的写入所有成员。例如:
struct OBJECT {
int number;
char letter;
} obj;
obj.number = 15;
obj.letter = ‘M’;
fout.write((char *)(&obj), sizeof(obj));
文件读取:
ifstream fin("file.dat", ios::binary);
fin.read((char *)(&obj), sizeof(obj));
这里不过多解释,他与文件写入基本相同。
读写文件的一些方法:
读时:
方法get()
每次返回一个字符。
方法ignore(int,char)
, 跳过一定数量的某个字符, 但你必须传给它两个参数。第一个是需要跳过的字符数。 第二个是一个字符, 当遇到的时候就会停止,例如:
fin.ignore(100, '\n');
跳过100个字符,或者不足100的时候,跳过所有之前的字符,包括 '\n'
写时:
put(char)
, 它每次向输出流中写入一个字符。
随机读写文件:
通过移动文件读写指针,可在文件指定位置进行读写,相关函数有:
seekg
(绝对位置); //绝对移动 //输入流seekg
(相对位置,参照位置); //相对操作tellg()
;// 返回当前指针位置 //输出流seekp
(绝对位置); //输出流seekp
(相对位置,参照位置); //相对操作tellp()
//返回当前指针位置
参照位置:
ios::beg
= 0 //相对于文件头ios::cur
= 1 //相对于当前位置ios::end
= 2 //相对于文件尾
代码例如:
#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;
class Employee{
private:
int number,age;
char name[20];
double salary;
public:
Employee(){};
Employee(int num,const char Name[],int Age,double Salary){
number=num;
strcpy(name,Name);
age=Age;
salary=Salary;
}
void display(){
cout<<number<<"\t"<<name<<"\t"<<age<<"\t"<<salary<<endl;
}
};
int main()
{
ofstream fout("./employee.bat",ios::out|ios::binary);
Employee e1(1,"张三",30,2300);
Employee e2(2,"李四",40,3000);
Employee e3(3,"王五",50,4000);
Employee e4(4,"刘六",60,5000);
fout.write((const char *)&e1,sizeof(e1));
fout.write((const char *)&e2,sizeof(e2));
fout.write((const char *)&e3,sizeof(e3));
fout.write((const char *)&e4,sizeof e4);
//这里实现将e3年龄进行修改
Employee e5(3,"王五",30,4000);
fout.seekp(2*sizeof(e1),ios::beg);
fout.write((const char *)&e5,sizeof(e5));
fout.close();
Employee e7;//读取一条王五的信息
ifstream fin("./employee.bat",ios::in|ios::binary);
fin.seekg(2*sizeof(e1),ios::beg);
fin.read((char *)&e7,sizeof(e7));
fin.close();
e7.display();
return 0;
}
文件复制:
方法一(逐个字符复制)
#include < fstream >
std::ifstream input("in",ios::binary);
std::ofstream output("out",ios::binary);
char ch;
while (input.get(ch)) output << ch;
方法二 (逐行复制)(注意使用这种方式input>>ch,他会默认跳过空白) 可以使用 input.unsetf(ios::skipws)
#include < fstream >
#include < string >
std::ifstream input("in",ios::binary);
std::ofstream output("out",ios::binary);
std::string line;
while (getline(input,line)) output << line << "\n";
方法三 (缓冲区复制) 最推荐使用并且效果极好
#include < fstream >
std::ifstream input("in",ios::binary);
std::ofstream output("out",ios::binary);
output << input.rdbuf();
方法四 (迭代器方法)
#include<fstream>
#include<iterator>
#include<algorithm>
istreambuf_iterator<char> begin_source(source);
istreambuf_iterator<char> end_source;
ostreambuf_iterator<char> begin_dest(destination);
copy(begin_source, end_source, begin_dest);