C++;文件流打开模式不明确 < P>在C++中执行文件IO,我们使用OFFROW、IFFSTATE和FSROW类。 ofstream:要在文件上写入的流类 ifstream:从文件读取的流类 fstream:读取和写入文件的流类
将文件与流对象关联的过程称为“打开文件”。 打开文件时,我们可以指定打开文件的模式。 我的查询与C++;文件流打开模式不明确 < P>在C++中执行文件IO,我们使用OFFROW、IFFSTATE和FSROW类。 ofstream:要在文件上写入的流类 ifstream:从文件读取的流类 fstream:读取和写入文件的流类,c++,file-io,stream,C++,File Io,Stream,将文件与流对象关联的过程称为“打开文件”。 打开文件时,我们可以指定打开文件的模式。 我的查询与ios::out和ios:in模式相关 当我创建一个of stream对象并在模式下用ios::打开文件时,我能够 写入文件,但仅在文件已创建时写入(如果文件不存在,还将使用ios::out模式创建文件) 但是,当我创建ifstream对象并使用ios::out模式打开文件时,我能够读取文件 我的问题是,当流的类型(ifstream/)本身指定正在执行的操作类型(输入/输出)时,为什么这些模式(ios
ios::out
和ios:in
模式相关
当我创建一个of stream
对象并在模式下用ios::打开文件时,我能够
写入文件,但仅在文件已创建时写入(如果文件不存在,还将使用ios::out
模式创建文件)
但是,当我创建ifstream
对象并使用ios::out
模式打开文件时,我能够读取文件
我的问题是,当流的类型(ifstream
/)本身指定正在执行的操作类型(输入/输出)时,为什么这些模式(ios::in
/)由语言提供
还有,为什么这种模棱两可的用法(of stream
withios::in
和ifstream
withios::out
)在一种情况下有效,而在另一种情况下失败(尽管仅当文件不存在时) 因为模式不限于输入/输出。例如,ifstream
的构造函数如下所示:
explicit ifstream ( const char * filename, ios_base::openmode mode = ios_base::in );
注意,默认值是
中的ios_base::in,因此您不必自己指定它。但是,模式
设置的流标志不限于输入
/输出
,而是包括:
app
(append)在每次输出操作之前,将流的位置指示器设置为流的末尾
ate
(在末尾)打开时,将流的位置指示器设置为流的末尾
代码>二进制< /代码>(二进制),将流视为二进制而不是文本。
中的(输入)允许对流进行输入操作
out
(输出)允许对流执行输出操作
trunc
(truncate)任何当前内容都将被丢弃,假设打开时的长度为零
流的、ifstream
和fstream
类都是底层filebuf
的高级接口,可以通过流的rdbuf()
成员函数获得这些接口
根据标准,当您使用某种模式打开流的时,它会像使用模式| ios_base::out
一样打开下划线流缓冲区。类似地,ifstream
使用模式| ios_base::in
fstream
将模式
参数逐字传递到下划线流缓冲区
上面的意思是,以下代码使用完全相同的打开标志打开文件:
fstream f("a.txt", ios_base::in | ios_base::out);
ifstream g("a.txt", ios_base::out);
ofstream h("a.txt", ios_base::in);
在这些行之后,您可以使用f.rdbuf()
、g.rdbuf()
和h.rdbuf()
执行完全相同的操作,所有这三种操作就像您使用C调用fopen(“a.txt”、“r+”)
打开文件一样,它提供您读/写访问权限,不会截断文件,如果文件不存在,则会失败
那么,为什么我们有三个不同的班级呢?正如我已经说过的,这些是高级类,在低级流缓冲区上提供高级接口。其思想是,ifstream
有用于输入的成员函数(如read()
),ofstream
有用于输出的成员函数(如write()
),而fstream
两者都有。例如,您不能这样做:
g.write("abc", 3); // error: g does not have a write function
但这是可行的,因为尽管g
是一个ifstream
,但我们已经用ios\u base::out
打开了它:
g.rdbuf()->sputn("abc", 3); // we still have write access