第七周 输入输出和模板
1.输入输出流相关的类
2.用流操纵算子控制输出格式
3.文件读写(一)
4.文件读写(二)
5.函数模板
6.类模板
7.类模板与派生、友元和静态成员变量
文件和流是一回事,可以将顺序文件看作一个有限字符构成的顺序字符流,然后像对cin, cout 一样的读写。回顾一下输入输出流类的结构层次:
istream是用于输入的流类,cin就是该类的对象。
ostream是用于输出的流类,cout就是该类的对象。
ifstream是用于从文件读取数据的类。
ifstream是用于向文件写入数据的类。
iostream是既能用于输入,又能用于输出的类。
fstream 是既能从文件读取数据,又能向文件写入数据的类。
ifstream和ifstream有的成员fstream 都有。
创建文件
#include // 包含头文件
ofstream outFile(“clients.dat”, ios::out|ios::binary);//构造函数
//创建文件
– clients.dat” 要创建的文件的名字
– ios::out 文件打开方式
• ios:out 输出到文件, 如果这个文件已经存在,则删除原有内容
• ios::app 输出到文件, 如果这个文件已经存在,则保留原有内容,总是在尾部添加
– ios::binary 以二进制文件格式打开文件
也可以先创建ofstream对象,再用 open函数打开
ofstream fout;
fout.open("test.out",ios::out|ios::binary);
判断打开是否成功:(如果文件名不合法、内存空间不足、新建文件和已存在只读文件同名等情况会创建失败)
if(!fout){
cout << “File open error!”<<endl;
}
文件名可以给出绝对路径,也可以给相对路径。没有交代路径信息,就是在当前文件夹(可执行文件所在文件夹)下找文件。
文件名的绝对路径和相对路径
绝对路径:
“c:\tmp\mydir\some.txt”
相对路径:
“\tmp\mydir\some.txt”:当前盘符的根目录下的tmp\dir\some.txt
“tmp\mydir\some.txt”:当前文件夹的tmp子文件夹里面的……
“…\tmp\mydir\some.txt”:当前文件夹的父文件夹下面的tmp子文件夹里面的……
“…\…\tmp\mydir\some.txt”:当前文件夹的父文件夹的父文件夹下面的tmp子文件夹里面的……
文件的读写指针
对于输入文件,有一个读指针;
对于输出文件,有一个写指针;
对于输入输出文件,有一个读写指针;
指针用来标识文件操作的当前位置, 该指针在哪里,读写操作就在哪里进行。
写指针例子:
ofstream fout("a1.out",ios::app); //以添加方式打开
long location = fout.tellp(); //取得写指针的位置
location = 10;
fout.seekp(location); // 将写指针移动到第10个字节处
fout.seekp(location,ios::beg); //从头数location,location为正数
fout.seekp(location,ios::cur); //从当前位置数location,location负值往前,正值往后
fout.seekp(location,ios::end); //从尾部数location,location 为负值
读指针例子:
ifstream fin(“a1.in”,ios::ate);
//打开文件,ios::ate表示定位文件指针到文件尾,意义是可以取文件长度
long location = fin.tellg(); //取得读指针的位置,这就是文件的字节长度
location = 10L;
fin.seekg(location); // 将读指针移动到第10个字节处
fin.seekg(location,ios::beg); //从头数location
fin.seekg(location,ios::cur); //从当前位置数location
fin.seekg(location,ios::end); //从尾部数location
location 可以为负值
显式关闭文件
ifstream fin(“test.dat”,ios::in);
fin.close();
ofstream fout(“test.dat”,ios::out);
fout.close();
字符文件读写
因为文件流也是流,所以流的成员函数和流操作算子也同样适用于文件流。
写一个程序,将文件 in.txt 里面的整数排序后,输出到out.txt
例如,若in.txt 的内容为:
1 234 9 45 6 879
则下面本程序后,生成的out.txt的内容为:
1 6 9 45 234 879
#include
#include
#include
#include
using namespace std;
int main() {
vector<int> v;
ifstream srcFile("in.txt",ios::in);
ofstream destFile("out.txt",ios::out);
int x;
while( srcFile >> x )
v.push_back(x);
sort(v.begin(),v.end());
for( int i = 0;i < v.size();i ++ )
destFile << v[i] << " ";
destFile.close();
srcFile.close();
return 0;
}
读写文件时打开的文件一定要关闭,否则会出问题。
比如写文件后如果不关闭,可能会导致写入的内容没有刻到硬盘上,而只是存在内存中,随后消失了,后果是很多内容没有真的写下来。原因是,访问内存比访问硬盘要快得多,为了效率,写入文件时是先存在内存缓冲区的,等到存满了再刻到硬盘上,关闭文件会出发这个操作,但是如果不关闭可能在刻到硬盘之前,应该要写入的内容就在内存上被覆盖而消失了。
再比如,通常操作系统能同时打开的文件数是有上限的,如果只打开文件不关闭导致达到上限,接下来就无法打开任何文件了。
等等。。。