c++IO库之文件输入输出详细整理,建议赶紧收藏!!!
Posted 大忽悠爱忽悠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++IO库之文件输入输出详细整理,建议赶紧收藏!!!相关的知识,希望对你有一定的参考价值。
c++IO库之文件输入输出
引言
- 头文件fstream定义了三个类型来支持文件IO: ifstream从一个给定文件读取数据,ofstream向一个给定文件写入数据,以及fstream可以读写给定文件。
- 这些类型提供的操作与我们之前使用过的对象cin和cout的操作一样。特别是,我们可以用IO运算符(<<和>>)来读写文件,可以用getline从一个ifstream读取数据。
- 除了继承自iostream类型的行为之外,fstream中定义的类型还增加了一些新的成员还管理与流相关的文件。除了这些操作,我们可以对fstream,ifstream和ofstream对象调用这些操作,但不能对其他IO类型调用这些操作。
fstream的特有的操作
fstream fstrm | 创建一个未绑定的文件流。fstream是头文件中定义的一个类型 |
fstream fstrm(s) | 创建一个fstream,并打开名为s的文件。s可以是string类型,或者是一个指向C风格字符串的指针。这些构造函数是explicit的。默认的文件模式mode依赖于fstream的类型 |
fstream fstrm(s,mode) | 与前一个构造函数相似,但按指定mode打开文件 |
fstrm.open(s) | 打开名为s的文件,并将文件与fstrm绑定。s可以是一个string或一个指向C风格字符串指针。默认的文件mode依赖于fstream的类型。返回void. |
fstrm.close() | 关闭与fstrm绑定的文件,返回void |
fstrm.is_open() | 返回一个bool值,指出与fstrm关联的文件是否成功打开且尚未关闭 |
使用文件流读对象
- 当我们想要读写一个文件时,可以定义一个文件流对象,并将对象与文件关联起来。
- 每个文件流都定义了一个名为open的成员函数,它完成一些系统相关的操作,来定位给定的文件,并视情况打开为读或写模式。
- 创建文件流对象时,我们可以提供文件名(可选的)。如果提供了一个文件名,则open会自动被调用:
ifstream in(ifile);//构造一个ifstream并打开给定文件
ofstream out;//输出文件流未关联到任何文件
- 定义一个输入流in,它被初始化为从文件中读取数据,文件名由string类型的参数iflie指定。
- 输出流out未与任何文件关联。
- 在新c++标准中,文件名既可以是string类型,也可以是C风格字符串指针。
- 旧版本的标准库只可以使用C风格字符串数组。
用fstream代替iostream&
- 再要求使用基类型对象的地方,我们可以用继承类型的对象来替代。这意味着,接受一个iostream类型引用(或指针)参数的函数,可以用一个对象的fstream(或sstream)类型来调用。
- 也就是说,当有一个函数接受一个ostream&参数,我们可以传给它一个ofstream对象,对istream&和ifstream同理.
- 下面举一个例子:
#include<iostream>
using namespace std;
#include<fstream>
class Book
{
public:
Book():sellSum(0),isbn(0),price(0){}
int isbn;//书本的编号
int price;//书本的价格
int sellSum;//该书的销售总额
};
//输入卖出书本的编号,价格
istream& read(istream& is, Book& item)
{
int sumValue = 0;
//从文件中读取信息存入item中
is >> item.isbn >> item.price;
return is;
}
//输出卖出书本的编号,价格和销售总额
ostream& print(ostream& os, Book& item)
{
//输出信息并写入当前文件中
cout<<"当前书本的编号为: " << item.isbn << " 价格: " << item.price << " 销售总额: " << item.sellSum << endl;
os << "当前书本的编号为: " << item.isbn << " 价格: " << item.price << " 销售总额: " << item.sellSum << endl;
return os;
}
int main(int argc, char** argv)
{
ifstream input("read.txt");//打开销售记录文件
if (!input.is_open())
cerr << "文件打开失败" << endl;
ofstream output("print.txt");//打开输出文件
if (!output.is_open())
cerr << "文件打开失败" << endl;
Book total;//保存销售总额变量
while (read(input,total))//读取销售记录
{
total.sellSum += total.price;
print(output, total) << endl;
}
return 0;
}
重要的部分是对read和print的调用,虽然两个函数定义时指定的形参分别是istream&和ostream&,但我们可以向他们传递fstream对象
成员函数open和close
- 如果我们定义了一个空文件流对象,可以随后调用open来将它与文件关联其起来:
ifstream in(ifile);//构筑一个ifstrean并打开给定文件
ofstream out;//输出文件流未与任何文件关联
out.open(ifile + ".copy");//打开指定文件
- 如果调用open失败,failbit会被置位.
failbit用来指出一个IO操作失败了
因为调用open可能失败,进行open是否成功的检测是一个好习惯:
if(out)//检查open是否成功,如果open成功,我们就可以使用文件了
- 一旦一个文件流已经打开,它就保持与对应文件的关联.
实际上,对一个已经打开的文件流调用open会失败,并会导致failbit被置位.
随后的试图使用文件流的操作都会失败。 为了将文件流关联到另外一个文件,必须首先关闭已经关联的文件。一旦文件成功关闭,我们可以打开新的文件。
in.close();//关闭文件
in.open(ifile+"2");//打开另外一个文件
自动构造和析构
#include<iostream>
using namespace std;
#include<fstream>
#include<vector>
#include<string>
istream& read(istream& is, string& item)
{
int sumValue = 0;
is >> item;
return is;
}
void print(string& item)
{
//输出信息
cout<<item << " ";
}
int main(int argc, char** argv)
{
vector<string> s = { "1.txt","2.txt","3.txt","4.txt","5.txt" };
string item;
for (int i = 0; i < s.size(); ++i)
{
ifstream input(s[i]);
read(input, item);
print(item);
}
return 0;
}
- 每个循环构造一个新的名为input的ifstream对象,并打开它来读取给定的文件。
- 因为input是while循环的局部变量,它在每个循环步中都要创建和销毁一次
- 当一个ifstream离开其作用域时,与之关联的文件会自动关闭。
- 在下一步循环中,input会再次被创建
当一个fstream对象被销毁时,close会被自动调用
文件模式
- 每个流都有一个关联的文件模式,用来指出如何使用文件。
- 下表列出了文件模式和它们的含义:
in | 以读的方式打开 |
out | 以写的方式打开 |
app | 每次写操作前均定位到文件末尾 |
ate | 打开文件后立即定位到文件末尾 |
trunc | 截断文件 |
binary | 以二进制方式进行IO |
无论哪种方式打开文件,我们都可以指定文件模式,调用open打开文件时可以,用一个文件名初始化流来隐式打开文件可以。指定文件模式有如下限制:
- 只可以对ofstream或fstream对象设定out模式
- 只可以对ifstream或fstream对象设定In模式
- 只有当out也被设定时才可以设定trunc模式
- 只要trunc没被设定,就可以设定app模式,在app模式下,即使没有显示指定out模式,文件也总是以输出方式被打开
- 默认情况下,即使我们没有指定trunc,以out模式打开的文件也会被截断。为了保留以out模式打开的文件的内容,我们必须同时指定app模式,这样只会将数据追加写到文件末尾;或者同时指定in模式,即打开文件同时进行读写操作.
- ate和binary模式可以用于任何类型的文件流对象,且可以与其他任何文件模式组合使用。
每个文件流类型都定义了一个默认的文件模式,当我们未指定文件模式的时候,就使用默认模式。
与ifstream关联的文件默认以in模式打开;
与ofstream关联的文件默认以out模式打开;
与fstream关联的文件默认以in和out模式打开。
、
以out模式打开文件会丢失已有数据
默认情况下,当我们打开一个ofstream时,文件的内容会被丢弃。阻止一个ofstream清空给定文件内容的方法是同时指定app模式:
//在这几条语句中,file1都被截断
ofstream out("file1");//隐含的以输出模式打开文件并截断文件
ofstream ou2("file1",ofstream::out);//隐含的截断文件
ofstream out3("file1",ofstream::out|ofstream::trunc);
//为了保留文件内容,我们必须显示指定app模式
ofstream app("file2",ofstream::app);//隐含为输出模式
ofstream app2("file2",ofstream::out|ofstream::app);
保留被ofstream打开的文件中已有的数据的唯一方法是显示指定dpp或者in模式.
每次调用open时都会确定文件模式
对于一个给定流,每当打开文件时,都可以改变其文件模式:
ofstream out;//未指定文件打开模式
out.open("scratchpad");//模式隐含设置为输出和截断
out.close();//关闭out,以便我们将其用于其他文件
out.open("a",ofstream::app);//模式为输出和追加
out.close();
通常情况下,out模式意味着同时使用trunc模式,使用trunc模式打开一个已经写了数据的文件,文件里面的内容会被全部清空
每次打开文件时,都要设置文件模式,可能是显示设置,也可能是隐式地设置。当程序未指定模式前,就使用默认值
以上是关于c++IO库之文件输入输出详细整理,建议赶紧收藏!!!的主要内容,如果未能解决你的问题,请参考以下文章
Hive从入门到精通,HQL硬核整理四万字,全面总结,附详细解析,赶紧收藏吧!!