是否定义了流实现的默认模式?

时间:2017-02-23 10:15:09

标签: c++ c++11 iostream ofstream unspecified-behavior

给出以下代码:

string openUrl = ConfigurationManager.AppSettings["Google"];

当调用 .write(....)并使用 stdc ++ libc ++ 时,流处于二进制模式({{1} })。

然而,当使用 MSVC (2015 / 2017RC1)时,它似乎处于文本模式或奇怪的状态,因为生成的文件大于实际写入的文件。

但是,如果我明确设置模式<input id="Button1" type="button" value="button" onclick='window.open("<%= openUrl %>")' /> ,MSVC的行为与前面提到的其他标准库的<% string openUrl = System.Configuration.ConfigurationManager.AppSettings["Google"]; %> <input id="Button1" type="button" value="button" onclick='window.open("<%= openUrl %>")' /> 实现类似。

示例代码:

std::ofstream stream("somefile");

if (!stream)
{
   return 1;
}

使用msvc运行时上述代码的输出:

std::ios::binary

使用libc ++,stdc ++:

运行上述代码的输出
std::ios::binary

差异可能会变得更大,这取决于写入的数据量和数据的内容。

最后我的问题仍然是一样的,是未定义还是未指明的行为?

将上面的矢量更改为以下内容,使得示例更加明显。

std::ofstream

2 个答案:

答案 0 :(得分:5)

流构造函数使用的默认模式是ios_base::out。由于没有明确的text模式标志,这意味着流以文本模式打开。文本模式仅对Windows系统有影响,它将\n个字符转换为CR / LF对。在POSIX系统上,它没有任何效果,文本和二进制模式在这些系统上是同义词。

答案 1 :(得分:3)

当我使用g++libstdc++在Windows上运行代码时,我得到以下结果:

expect: 32
file size: 33

所以问题不是特定于编译器,而是特定于操作系统。

虽然C ++使用单个字符\n来表示以字符串结尾的行,但Windows对于以文件结尾的行使用两个字节0x0D0x0A。这意味着如果在文本模式下将字符串写入文件,则使用这两个字节写入所有出现的单个字符\n。这就是为什么你在示例的文件大小中获得额外字节的原因。