说双向文件声明不隐式设置标志是否正确
Is it correct to say that bidirectional file declarations do not set flags implicitly?
这里的这种说法似乎不正确:
另一方面,双向文件流没有标志 隐式设置。这是因为双向流 不必在所有情况下都处于输入和输出模式。你 可能想要打开双向流以进行只读或写入 只。因此,双向文件流没有隐式输入或 输出模式。您必须始终设置双向文件流的打开 模式显式。
否则,此代码将无法编译。
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
fstream file("novo.txt", ios::out);
char i;
file >> i;
}
语句适用于 gcc
这里的这种说法似乎不正确:[...]
我不知道标准或Visual Studio,但我知道我正在使用的C++,这是来自GCC的那个。在那里,您可以查看相关的标题。
oistream::open
看起来像这样:
inline void
istream::open(const char* __s, ios_base::openmode __mode = ios_base::in) {
if (!_M_filebuf.open(__s, __mode | ios_base::in))
所以你这里有两件事:一个默认的函数参数,以防你在调用方法时没有指定一个,以及一个强制标志,它总是被或进入提供的模式。因此,无论您指定哪种模式,输入模式都将始终添加到您的规范中。其他代码,特别是构造函数,将委托给此代码。类似的情况也发生在ofstream::open
.另一方面,fstream::open
有默认参数,但没有强制参数:
inline void
fstream::open(const char* __s,
ios_base::openmode __mode = ios_base::in | ios_base::out) {
if (!_M_filebuf.open(__s, __mode))
因此,不传递任何模式都是可以的(至少在这个实现中,但请阅读@kmote的答案以获取更多详细信息),但是如果您确实传递了任何模式,那么您必须传递in
或out
或两者兼而有之,因为不会将强制模式添加到您指定的模式中(或未指定)。
这是我阅读 Apache 文档的方式,来源支持我的观点,至少对于我的实现而言。由于所有这些都在模板化代码中,因此您可以查看来自不同编译器的标头,以了解它如何处理这些情况。因此,请查看VS标头,查找basic_fstream
并查看其方法是如何实现的。
缺少编译器错误
否则,此代码将无法编译。
代码打开一个双向流仅用于输出,然后尝试从中输入内容。没有理由无法编译。流的静态类型是fstream
的,即双向的。只有在运行时,您才会将具有特定含义的某个标志传递给构造函数。编译器(通常)不会检查这一点,因此当代码无法实际从流中读取时,代码在运行时将行为异常。
请注意,我不确定 Windows 是否真的支持仅打开文件进行输出。操作系统支持的唯一文件模式很可能是只读和读写。(请注意,我只是在这里推测。在这种情况下,即使在运行时,打开文件仅用于输出并在之后读取也不会有问题,因为仅使用 out
打开文件或使用 in|out
打开文件没有区别。为了便于移植,应该选择正确的模式,因为那里有支持只写文件的内核。
虽然历史上对这个问题存在一些混淆,但我相信你引用的说法确实具有误导性,但不是因为你的例子中的原因。双向文件流确实隐式设置了标志,如文档中所述:
void open(
const char *_Filename,
ios_base::openmode _Mode = ios_base::in | ios_base::out,
int _Prot = (int)ios_base::_Openprot
);
基于 Apache 语句,我不希望您的代码示例失败,因为它明确将标志设置为 ::out。另一方面,我希望这段代码失败:
int main()
{
fstream file("novo.txt");
char i;
file >> i;
}
但是根据 MSDN 文档,这段代码也不会失败,文件将默认为 ios_base::in & out(因此,Apache 语句并不完全准确)。
- 在 CMake 中为每个目标设置编译器/链接器标志
- 如何正确设置 ios 标志以进行流操作?
- 有关使用标志位设置内部错误标志的说明
- 如何在CMakeLists.txt中正确设置CMake标志
- 设置用于调试的 g++ 编译器标志
- 如何在Qt中取消设置标志?
- SDL_CreateWindow在设置标志时失败SDL_WINDOW_VULKAN
- 如何在 cmake 中设置编译器特定的标志
- 如何在图像位中设置标志以标记音频文件的结尾
- 添加 swig pythoncode 以在 Python 对象上设置自己的标志
- 如何在cmake中的源文件之后设置库标志?
- 为什么我必须将错误状态标志设置为 goodbit 才能使其工作
- while 循环是否在设置标志的情况下运行多次?
- 设置 Xcode 标志以便将 python 嵌入我的C++项目中
- STD :: Ostream忽略了通过setf()在基础上设置的十六进制标志
- 如何嵌入在C++中设置标志的 python 代码
- 检查是否为输入流设置了Skipws/noskipws标志
- Dlib:如何初始化一个忽略标志设置为1的mmodrect
- Cmake没有将汇编程序标志设置为armasm(对于WinCE)
- 调用WinHttpCreateUrl与ICU_REJECT_USERPWD标志设置在Windows 7中工作,但不Win