c++ - 从奇怪的版本字符串中提取数字

标签 c++

我有一个应用程序的版本号,格式为 0x00870016,其中前 4 位十六进制数字代表版本号的第一部分,后 4 位代表第二部分,因此在此示例中版本号为 135.22。

我正在尝试弄清楚(在 C++ 中)如何分别提取这些数字以将它们显示为字符串。

最佳答案

通过结合使用 mask 和移位:

int main()
{
    const uint32_t v = 0x00870016;
    const uint16_t major = (v & 0xFFFF0000) >> 16; 
    const uint16_t minor = v & 0x0000FFFF;
    cout << major << "." << minor << "\n";
}

输出:

135.22

解释:

0x00870016 是一个 32 位数字。您的主版本号由 16 位最高有效数字组成,次版本号由 16 位最低有效数字组成。

为了提取主版本号,让我们通过用 0xFFFF0000 屏蔽输入值来找出 16 位 MSBits -- 一个数字,其中所有 16 个最重要的数字都设置为1 并且所有的最小信号位都是0:

0x00870016 && 0xFFFF0000 = 0x00870000

结果值是您的主版本号,左移 16 位。所以让我们把它移过来:

0x00870000 >> 16 = 0x00000087

我们有您真正的主要版本号。

提取次要版本号是类似的,除了我们不必转移。

注意:

第一步可以通过跳过掩码来简化:

const uint16_t major = v >> 16;

这是有效的,因为 C++ 标准规定当您向右移动时,空出的位将填充 0。所以最终的程序是:

int main()
{
    const uint32_t v = 0x00870016;
    const uint16_t major = v >> 16;
    const uint16_t minor = v & 0x0000FFFF;
    cout << major << "." << minor << "\n";
}

编辑:

如评论中所述,您可能会得到字符串形式的 0x00870016,而不是数字。我们只需要将这个字符串转换成它的数字等价物。处理前导 0x 可能看起来像一个绊脚石,但如果您使用 C++ 标准库 iostream 操纵器就不是这样:

int main()
{
    const std::string inVer = "0x00870016";
    uint32_t v = 0;
    std::stringstream ss;
    ss << inVer;
    ss >> std::hex >> v;
    const uint16_t major = v >> 16;
    const uint16_t minor = v & 0x0000FFFF;
    cout << major << "." << minor << "\n";
}

关于c++ - 从奇怪的版本字符串中提取数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18514970/

相关文章:

c++ - C++中的条件运算符错误?

c++ - boost 属性树获取第一个元素

javascript - Emscripten OpenGL (3) 给出版本错误

c++ - 通知格式错误的模板实例化的最佳方式是什么?

c++ - Pimpl 成语 vs 纯虚拟类接口(interface)

c++ - 在编译时检测 ICC 与 GCC

c++ - std::future 如何影响关联的 std::packaged_task 的生命周期?

c++ - '_wctime3 2' : cannot convert parameter 1 from ' const time_t *' to ' const __time32_t *'

c++ - 优化定点平方

c# - 使用命名管道将图像从 C++ 发送到 C# 应用程序