C++ std::streampos、std::streamoff和std::streamsize到long int?
为了测量流的位置/偏移量/大小,标准规定了C++ std::streampos、std::streamoff和std::streamsize到long int?,c++,file,c++11,stream,standards-compliance,C++,File,C++11,Stream,Standards Compliance,为了测量流的位置/偏移量/大小,标准规定了std::streampos、std::streamoff和std::streamsize,但它们是实现定义的 如何以安全且可移植的方式将这些类型转换为long-long-int?(例如,测量文件大小并将其插入以long-long int作为参数的函数)只需将值传递给需要long-long int的函数即可std::streamoff和std::streamsize都是有符号整数类型,std::streampos隐式转换为std::streamoff 编
std::streampos
、std::streamoff
和std::streamsize
,但它们是实现定义的
如何以安全且可移植的方式将这些类型转换为
long-long-int
?(例如,测量文件大小并将其插入以long-long int作为参数的函数)只需将值传递给需要long-long int的函数即可std::streamoff
和std::streamsize
都是有符号整数类型,std::streampos
隐式转换为std::streamoff
编辑:我假设一个断言streamsize/streamoff不大于
long
不会有什么坏处,以防有人提出了文件大小为128的问题。好吧,就C++98/03而言,没有long-long-int
。所以我假设你问的是C++11
streamsize
和streamoff
必须是整型的typedef(不是整数,因此您不会将其传递给任何需要long
的对象)。由于整型是基本类型,它们只能由C++定义或作为编译器特定定义。
因此,唯一的问题是:这些typedef是否大于long
?所有整数类型都可以转换为更大或大小相等的类型(尽管有符号/无符号,但此处的所有类型都是有符号的,因此没有问题)。但是如果它更大。。。你打算怎么办
假设您无法更改要“注入”的函数的签名(因为如果可以,没有理由不将streamsize
作为参数类型,从而避免问题),那么您没有任何选项。您的数据值大于函数的值。这里没办法绕过它
您可以在long
中执行静态强制转换以关闭编译器,但如果实际大小不能放入long
中,则这将无济于事
归根结底,这是一个棘手的问题。您有一个函数,它接受的参数对于您正在传递的内容来说可能太小。您所能做的最多就是通过static\u assert
检测何时可能出现问题。大概是这样的:
static_assert(sizeof(std::streamsize) <= sizeof(long long), "Oops.");
static\u assert(sizeof(std::streamsize)MINGW-64的短响应:std::streampos
具有一个到64位有符号整数类型的转换运算符std::streamoff
as
std::streampos pos = ...;
std::streamoff ofs = (std::streamoff) pos;
因此,例如,要查找文件的长度,只需打开std::ifstream
并计算
static unsigned long long getStreamSize(std::ifstream& is)
{
std::streampos savePos = is.tellg();
is.seekg(0, std::ios::end);
std::streampos endPos = is.tellg();
is.seekg(savePos);
return (std::streampos)endPos;
}
…或者认为STL是另一个孤岛…除了exabytes文件大小之外,在转换为long-long int时会出现问题吗?@Vincent:不会。整数类型可以转换为更大(或同等大小)的类型整数类型无问题。<代码> StuPoS< /COD>隐式转换为<代码> SurrOuts< /Cord>,因此您可以将其传递给期望“代码>长Lo/Cuth>的东西。<代码> StRoPOS < /C>和<代码> SuroOff之间的区别是对状态字符编码的支持。在C++标准中,它指定了<代码> TELG.()
返回一个整数类型,该类型表示从文件开始的字节数,并且是。seekg(0,std::ios::end)
是二进制流的未定义行为:“读写由类basic_filebuf
的对象控制的序列的限制与读写标准C库文件的限制相同。“看不清楚,你的问题是从哪里来的。规范是规范,用例是用例,这次不相交。cplusplus.com不仅没有参考,实际上也不是很准确。只是因为cplusplus.com说了一些不真实的事情。:)我们理解,“标准”设计没有预见到有人会要求文件大小为整数,这是毫无用处的。如果这是获得文件大小的标准方法,蝙蝠侠,请回答我这个问题:为什么C++17添加了std::filesystem::file_size
?嗯,因为它以前不在那里。。。我猜你不知道,一旦你要求一个文件大小,它就不再相关,使用它是一个等待发生的事情?我按照更高的标准编写代码,然后根据语言规范编写错误和显式未定义行为。在MINGW-64/g++中,std::streampos似乎是特定于实现的,std::streamoff是一个整型、带符号的64位整数。@SamGinrich这就是我描述的,不是吗?