Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::streampos、std::streamoff和std::streamsize到long int?_C++_File_C++11_Stream_Standards Compliance - Fatal编程技术网

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这就是我描述的,不是吗?