C++ 使用C+编写二进制文件+;:默认的区域设置重要吗?

C++ 使用C+编写二进制文件+;:默认的区域设置重要吗?,c++,binary,locale,fstream,C++,Binary,Locale,Fstream,我的代码使用设置了二进制标志的fstream和未格式化的I/O函数读写来处理二进制文件。这在我使用过的所有系统上都能正常工作(文件中的位完全符合预期),但这些基本上都是美国英语。我一直在想这些字节是否有可能被另一个系统上的编解码器修改 这听起来像是标准说使用无格式I/O的行为与使用sputc/sgetc将字符放入streambuf的行为相同。这些将导致调用Stulbf中的溢出或下溢功能,并且听起来类似于导致某些CODDEVT(例如,参见C++标准中的27.81.4.3)。27.8.1.1.5中规

我的代码使用设置了二进制标志的fstream和未格式化的I/O函数读写来处理二进制文件。这在我使用过的所有系统上都能正常工作(文件中的位完全符合预期),但这些基本上都是美国英语。我一直在想这些字节是否有可能被另一个系统上的编解码器修改

这听起来像是标准说使用无格式I/O的行为与使用sputc/sgetc将字符放入streambuf的行为相同。这些将导致调用Stulbf中的溢出或下溢功能,并且听起来类似于导致某些CODDEVT(例如,参见C++标准中的27.81.4.3)。27.8.1.1.5中规定了创建此编解码器的基本文件BUF。这使得结果看起来似乎取决于basic_filebuf.getloc()返回的内容

所以,我的问题是,我是否可以假设在一个系统上使用ofstream.write写出的字符数组可以在另一个系统上使用ifstream.read逐字恢复,而不管任何人在他们的系统上使用的是什么语言环境配置?我会作出以下假设:

  • 程序正在使用默认值 区域设置(即,程序不可用) 更改区域设置本身 完全没有)
  • 这两个系统都有字符位8,每个字节内的位顺序相同,将文件存储为八位字节,等等
  • 流对象设置了二进制标志
  • 在这个阶段,我们不需要担心任何持久性差异。如果要将数组中的任何字节解释为多字节值,将在稍后阶段根据需要处理endianess转换

  • 如果默认的区域设置不能保证在某些系统配置(不知道,阿拉伯语或某些东西)上没有经过修改,那么在Windows上使用C++(

    < p>)写二进制文件的最好方法是什么,应该是好的,但是在其他操作系统上,你也应该检查行结尾(就像安全一样)。默认的C/C++语言环境是“C”,它不依赖于系统的语言环境


    这不是保证。正如您所知,C/C++编译器及其目标机器差别很大。所以,如果你坚持这些假设,你就在等待麻烦的到来。更改区域设置的开销可以忽略不计,除非您尝试将其设置为每秒数百次。

    如果设置了二进制标志,则您所写的所有内容都将逐字写入文件。没有转换。如何解释字节取决于您(可能还有语言环境)

    还有一件事:在不同的地区有可能发生破损。例如,如果您的数据源创建了基于区域设置的二进制数据(并且此数据的格式将根据区域设置而改变-顺便说一句,这是一个坏主意)。这将导致在具有不同区域设置的计算机上加载数据时出现问题。但这是一个设计错误


    如果您只使用具有相同格式/布局的标准数据类型/结构,无论它们是在什么语言环境中创建的,那么一切都应该正常。

    谢谢您的帮助。我只是觉得发布一些不适合评论的附加信息可能会有所帮助

    < > C++程序的默认位置始终是“C”区域()。如果这是程序中使用的唯一语言环境,则表示该行为不取决于运行它的机器的特定语言环境配置。这还意味着字符的未格式化I/O不会进行任何代码转换(不过wchar\u t可能是另一回事)。这意味着(给定问题中的假设)读写应该允许不经修改地恢复二进制数据


    (阅读文档)您可以通过调用setlocale(LC_ALL,“”)全局设置应用程序的区域设置以匹配系统默认设置,这意味着从该点构造的流将使用系统默认区域设置。要将其设置回“C”语言环境,您可以调用setlocale(LC_ALL,“C”),这意味着这就是将来构建的流将使用的语言环境。您还可以指定“C”本地值应用于已通过调用stream.imbue(locale::classic())构造的流。

    我认为您应该在假设中添加相同的字节顺序。还是我完全错了?@TheScottMachine:Space\u C0wb0y是对的,给你的假设添加相同的字节顺序谢谢,我添加了一个额外的假设来澄清。谢谢,关于默认语言环境的信息就是我要找的。我认为只要在流上设置二进制标志,行的结尾就不重要了。