IO流是否可移植

Are IO streams portable

本文关键字:可移植 是否 IO      更新时间:2023-10-16

我想知道IO流是否真的是可移植的(我认为它们应该是,但希望确定)?尤其是在处理unix和windows中使用的文件时。

特别是如果我将一个双值转储到windows中的文件中,然后读取相同的值在使用iostreams的文件中的unix上,它不会因为变化而引起问题吗在两个操作系统的端序中?

格式化的io怎么样?我在哪里读到,不确定在哪里,当涉及到操作格式化数据时,windows和unix处理相同数据的方式有一些不同。谁能谈谈这个问题吗?

C++标准是抽象的,没有提到任何特定的操作系统(AFAIK)。因此,iostream库是可移植的。话虽如此,C++标准允许某些实现细节,包括一些对用户可见的(而不仅仅隐藏在标准C++库中)依赖于实现。这允许操作系统和/或编译器的提供者选择他们的首选方式来实现C++标准。

任何依赖于实现相关行为的代码显然都是不可移植的,即使在同一操作系统和/或编译器的不同版本中也是如此。换句话说,应该避免这种代码。

注意:有时需要编写依赖于实现的代码。在这种情况下,保护代码不破坏假定的依赖于实现的行为是至关重要的。例如,程序可以假定sizeof(long unsigned)==8。在这种情况下,至少static_assert(sizeof(long unsigned)==8,"long unsigned not 8 bytes")应该停止编译无效代码,但理想情况下,应该存在一个替代版本,并通过模板魔术(或C风格宏)进行选择。C++11标准实际上为std::uint64_t类型提供了保证的sizeof(std::uint64_t)==8(及类似),以避免此类问题。然而,sizeof(ostream)仍然依赖于实现。

它是可移植的,如果你从一个系统中写入一个特定的字节序列,并将该序列传输到另一个系统(通过文件或套接字,这并不重要),你就可以在另一端读回相同的字节序列。如果你在文本模式而不是二进制模式下写作或阅读,那么行尾(我认为理论上其他实现定义的特殊字符)可能会被重新解释。

不可移植的是double作为字节序列的精确表示,二进制格式。例如,二进制是因为endian-ness,而格式化是因为运行库中的细微差异,这可能意味着当一个系统编码为字符串,另一个系统返回double时,即使您输出的精度应该足够的小数位数,结果也可能会有ulp(有时甚至更大)的不同。NaN值的字符串表示也留给实现。

就C++标准而言,double不需要是IEEE双精度值。因此,理论上,二进制表示之间可能没有任何共同点,在进行格式化I/O时,可以表示哪些值,从而输出/接受哪些字符串方面也存在很大差异。在实践中,IEEE是常用的,字符串通常不会在浮点运算中引入比预期更多的错误。

文件输入输出:是的,它们是兼容的。Unix中的比特流与windows中的比特流量相同。Unix中的双值与Windows中的相同,因为两者都遵循标准。

格式化:我不知道任何二进制格式(在double的例子中),你可能在谈论文本。windows中的文本格式与Unix不同,这是导致许多问题的原因。

二进制接口/代码可移植性:如果您使用IO的函数,则它是不可移植的。std::输入/输出流,即f/o/stream实现是不可移植的,也不是为可移植而设计的。