打开文件
1.用文件流的成员函数open()打开文件
ifstream,ofstream、fstream等三个文件流类中各有一个成员函数open():
voidifstream::open(const char *, int = ios::in, int = filebuf::openprot);
voidofstream::open(const char *, int = ios::out, int = filebuf::openprot);
voidfstream::open(const char *, int =filebuf::openprot);
参数说明:
第一个参数为要打开的文件名(课含盘符和文件名)。
第二个参数指定文件的打开方式。输入文件流的默认值ios::in,意思是按输入文件方式打开文件;输出文件流的默认值ios::out,意思是按输出文件方式打开文件;对于输入输出文件流没有默认的打开方式,再打开文件时需注明打开的方式。
第三个参数是指打开文件的保护方式,该参数和操作系统有关,通常使用默认值filebuf::openprot。
下表是对文件打开方式的说明:
打开方式 | 说明 |
in | 读方式打开文件 |
out | 单用,打开文件时,若文件不存在,则产生一个空文件;若文件存在,则清空文件 |
ate | 必须与in、out或norelace组合使用。如out|ate,其作用是在文件打开时将文件指针移至文件末尾,文件原有内容不变,写入的数据追加到文件末尾 |
app | 是以写追加方式打开,当文件存在,它等于out|ate;而文件不存在时,他等价于out |
tunc | 打开文件时,若单用,则与out等价 |
nocreate | 打开文件时,若文件不存在,则打开失败。这种方式总是和读或写方式组合使用,但不能怨noreplace组合使用 |
noreplace | 用来创建一个新文件,不单用,总是与写方式组合使用。若与ate或app组合使用,也可以打开一个已有文件 |
binary | 以二进制方式打开文件,总是与读或写方式组合使用。不以binary方式打开的文件,都是本文件 |
2.用文件流类的构造函数打开文件
ifstream,ofstream、fstream等三个文件流类类的构造函数所带的参数与各自的成员函数open()所带的参数完全相同。因此,在说明这3种文件流类的对象时,通过调用各自的构造函数也能打开文件。
例如:
ifstreamf1("file1.dat");
ofstreamf2("file2.txt");
fstreamf3("file3.dat",ios::in);
3.打开文件后判断打开的是否成功
判断文件打开与否的语句为:
if (!f1)
{
cout << "不能打开文件:C:\\MyProgram\\file.dat\n"; exit(1));
}
或
ifstream f2;
f2.open("fiel.dat",ios::in || ios::nocreate);
if (!f2)
{
cout << "不能打开输入文件:file.dat\n"; exit(1));
}
若文件打开成功,则“!f1”为0,否则“!f1”为非0.打开输入文件时,若指定ios::nocreate,则文件不存在打开失败;否则若文件不存在,人会产生一个空的输入文件。
注:判断文件打开与否的语句也可写成:
if (f1.fail())
{
cout << "不能打开文件:C:\\MyProgram\\file.dat\n"; exit(1));
}
3.关闭文件
文件读/写完毕,通常要关闭文件,其目的是把暂存在内存缓冲区中的内容写到文件中,并归还打开文件时申请的内存资源。
ifstream,ofstream、fstream等三个文件流类中各有一个成员函数关闭文件,用法相同:
voidifstream::close();
voidofstream::close();
voidfsream::close();
例如:
ifstreaminfile("f1.dat");
infile.close();
文件的读写
例:复制文本文件
#include"iostream"
#include"fstream"
using namespace std;
void main()
{
charch, f1[256], f2[256];
cout << "请输入源文件名?";
cin >> f1; //输入文件名
cout << "请输入目标文件名?";
cin>> f2;
ifstream in(f1,ios::in); //创建源文件流对象f1
ofstream out(f2); //创建目标流对象f2
if(!in)
{
cout << "\n不能打开源文件:" << f1;
return;
}
if(!out)
{
cout << "\n不能打开目标文件:" << f2;
return;
}
in.unsetf(ios::skipws); //跳过空格
while(in >> ch)
out << ch; //写入字符
in.close(); //关闭目标文件
out.close(); //关闭源文件
cout << "\n复制完毕!";
}
输出结果:
请输入源文件名?1.txt
请输入目标文件名?2.txt
复制完毕!
二进制文件的读写
对二进制文件的读写要使用到文件流的成员函数read()和write()。读写时,数据不做任何变换,直接传送。
1.读操作
二进制文件的读操作使用成员函数read()
istream&istream::read(char *t, int n);
istream&istream::read(unsigned char *t, int n);
istream&istream::read(signed char *t, int n);
功能:从二进制文件中读取n个字节数据到t指针所指缓存区。
2.写操作
二进制文件的写操作使用成员函数write():
istream&istream::write(char *t, int n);
istream&istream::write(unsigned char *t, int n);
istream&istream::write(signed char *t, int n);
功能:将t所指缓冲区的前n个字节数据写入二进制文本。
例:将100以内的偶数存入二进制文件
#include"iostream"
#include"fstream"
using namespace std;
void main()
{
fstreamout("a.dat", ios::out | ios::binary);
if(!out)
{
cout<< "a.dat\n";
return;
}
for(int i = 2; i < 100; i += 2)
out.write((char*)&i, sizeof(int));
out.close();
cout << "\n程序执行完毕!";
}
3.文件的定位
对于输入流文件来说,用于读写位置定位的成员函数如下:
istream& istream::seekp(streampos); //绝对定位,相对于头文件
istream& istream::seekp(streampos,ios::seek_dir); //相对定位
streampos istream::seekp::tellp(); //返回当前文件读写位置
对预算输出流来说,用于文件定位的成员函数如下:
ostream&ostream::seekp(streampos); //绝对定位,相对于头文件
ostream&ostream::seekp(streampos,ios::seek_dir); //相对定位
Streamposostream::seekp::tellp(); //返回当前文件读写位置
其中streampos和是streamoff类型等同于long,而seek_dir在类ios中定义为一个共有的枚举类型:
Enumseek_dir
{
beg=0;
bur=1;
end=2;
}
说明:
(1)文件名中g是get的缩写,而p是put的缩写。
(2)文件读写位置以字节为单位。
(3)成员函数seekg(streampos)和seekp(streampos)都以文件开始处为参考点,将文件读写位置移到参数所指位置。
(4)成员函数seekg(streamoof,ios::seek_dir)和seekp(streamoff,ios::seek_dir)第二个参数的值是文件读写位置相对定位的参考点;第一参数的值是相对于参考点的移动值,若为负值,则前移,否则后移。
(5)设按输入方式打开二进制文件流对象,举例如下:
f.seekg(-10, ios::cur); //文件读写位置从当前位置前移10个字节
f.seekg(10, ios::cur); //文件读写位置从当前位置后移10个字节
f.seekg(-10, ios::end); //文件读写位置以文件尾为参考点,前移10个字节。若文件尾值为6000,则文件读写位置移到5990.
文件随机访问
例:将5-200之间的奇数存入二进制文件,并读取指定数据
#include"iostream"
#include"fstream"
using namespace std;
void main()
{
intx, i;
ofstreamout("data.dat", ios::out | ios::binary);
if(!out)
{
cout << "不能打开文件data.dat\n";
return;
}
for(i = 5; i < 200;i+=2)
out.write((char*)&i, sizeof(int));
out.close();
ifstreamf("data.dat", ios::in | ios::binary);
f.seekg(30 * sizeof(int)); //文件指针移动到指定位置
for(i = 0; i < 10 & !f.eof(); i++)
{
f.read((char*)&x,sizeof(int));
cout<< x << endl;
}
f.close();
}
输出结果如下:
65
67
69
71
73
75
77
79
81
83
请按任意键继续. . .