为了在C ++中执行文件IO,我们使用ofstream,ifstream和fstream类。
将文件与流对象相关联的过程称为“打开文件”。
打开文件时,我们可以指定打开文件的模式。
我的查询与ios::out
和ios:in
模式有关。
当我创建ofstream
对象并使用ios::in
模式打开文件时,我能够
写入文件,但前提是它已创建(如果尚未存在,则创建ios::out
模式文件)。
但是当我创建ifstream
对象并使用ios::out
模式打开文件时,我可以从文件中读取。
我的问题是,当流的类型(ios::in
/ ios::out
)本身指定时,这些模式(ifstream
/ ofstream
)由语言提供的原因正在执行哪种类型的操作(输入/输出)?
另外,为什么这种含糊不清的用法(ofstream
与ios::in
和ifstream
与ios::out
)在一种情况下有效并且失败(尽管仅在文件尚未存在的情况下)另一个?
答案 0 :(得分:12)
ofstream
,ifstream
和fstream
类是底层filebuf
的高级接口,可以通过rdbuf()
成员函数获取流。
根据标准,当您使用某种模式ofstream
打开mode
时,它会像mode | ios_base::out
一样打开下划线流缓冲区。类似地ifstream
使用mode | ios_base::in
。 fstream
将mode
参数逐字传递给下划线流缓冲区。
以上含义是以下代码打开具有完全相同的打开标志的文件:
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调用{{1}打开文件一样,它提供读/写访问权限,不截断文件,如果文件不存在则失败。
那么,为什么我们有三个不同的班级?正如我已经说过的,这些是高级类,在低级流缓冲区上提供高级接口。我们的想法是fopen("a.txt", "r+")
具有输入的成员函数(如ifstream
),read()
具有输出的成员函数(如ofstream
),而write()
具有两者。例如,你不能这样做:
fstream
但是这有效,因为虽然g.write("abc", 3); // error: g does not have a write function
是g
,但我们用ifstream
打开了它:
ios_base::out
答案 1 :(得分:0)
因为模式不限于输入/输出。例如,ifstream
的构造函数如下所示:
explicit ifstream ( const char * filename, ios_base::openmode mode = ios_base::in );
请注意默认值为ios_base::in
,因此您无需自行指定。但是,mode
设置不限制为in
/ out
的流标记,但包括:
app
(append)在每次输出操作之前将流的位置指示器设置为流的末尾。ate
(最后)将流的位置指示器设置为打开时流的末尾。binary
(二进制)将流视为二进制而不是文本。in
(输入)允许对流进行输入操作。out
(输出)允许对流进行输出操作。trunc
(truncate)任何当前内容都会被丢弃,假设打开时长度为零。