10

To measure position/offsets/size of streams, the standard specify std::streampos, std::streamoff and std::streamsize, but they are implementation defined.

How to convert these types to long long int in a secure and portable way ? (for example to measure a file size and inject it in a function that take a long long int as argument)

4

3 回答 3

7

好吧,就 C++98/03 而言,没有 long long int. 所以我假设你在问 C++11。

streamsizeandstreamoff必须是整数类型的类型定义(不是streampos整数,所以你不会将它传递给任何需要 a 的东西long long)。由于整数类型是基本类型,它们只能由 C++ 定义或作为特定于编译器的定义。

因此,唯一的问题是:这些 typedef 是否大于long long?所有整数类型都可以转换为更大或相等大小的类型(尽管有符号/无符号,但这里的所有类型都是有符号的,所以没问题)。但如果它更大......你会怎么做呢?

假设您无法更改要“注入”它的函数的签名(因为如果可以,没有理由不将streamsize其作为参数类型从而避免问题),您没有任何选择。您的数据值大于函数采用的值。没有办法绕过它。

您可以在 a 中执行 static_castlong long以关闭编译器,但如果实际大小不适合 a ,这将无济于事long long

归根结底,这是一个棘手的问题。您有一个函数,该函数接受的参数对于您传递的内容可能太小。您最多可以通过static_assert. 像这样的东西:

static_assert(sizeof(std::streamsize) <= sizeof(long long), "Oops.");

老实说,我不会担心的。赔率很好,这long long将是您的编译器本机支持的最大整数大小。

于 2012-10-08T00:44:50.480 回答
2

只需将值传递给需要 long long 的任何函数。std::streamoffstd::streamsize都是有符号整数类型,并且std::streampos可以隐式转换为std::streamoff.

编辑:我想断言streamsize/streamoff 不会比long long不会伤害更大,以防有人提出__int128 文件大小。

于 2012-10-08T00:44:09.527 回答
-1

MINGW-64 的短响应:std::streampos具有到 64 位有符号整数类型的转换运算std::streamoff

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 是另一个岛屿 ...

于 2021-02-08T13:25:32.813 回答