【问题标题】:casting a string to a GUID does not give right result将字符串转换为 GUID 不会给出正确的结果
【发布时间】:2018-07-26 19:52:11
【问题描述】:

在我的程序中,我需要读取存储在 xml 文件中的 guid 值。这是xml文件的样子。

<data>
 <id>3AAAAAAA-BBBB-CCCC-DDDD-2EEEEEEEEEEE</id>
</data>

我的程序需要在 GUID 类型变量中读取此值。以下是我为此准备的。

#include "stdafx.h"
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <string>
#include <iostream>
#include <Windows.h>
namespace pt = boost::property_tree;
#pragma comment(lib, "rpcrt4.lib") 
int main()
{
    pt::ptree tree;
    std::string filename = "data.xml";

    pt::read_xml(filename, tree);

    std::string idStr = tree.get<std::string>("data.id");
    std::cout << "id as string = " << idStr << std::endl;
    GUID idAsGuid;

    auto res = UuidFromStringW((RPC_WSTR)idStr.c_str(), &idAsGuid);
    if (FAILED(res))
    {
        std::wcerr << L"Conversion failed with error: 0x" << std::hex << res << std::endl;
    }

   return 0;
}

变量 idStr 获取正确的值,但 idAsGuid 变量(即 GUID 类型)获取不正确的值(类似于 CCCCC-CCCC-CCCC-CCCCCCCCCCCCC)。我哪里错了?

【问题讨论】:

  • 关于术语的说明:这里没有casting
  • 你能指出我需要做什么演员吗?
  • 你使用一个函数来解析和理解一些输入字符串。铸造是例如将字符转换为整数,如static_cast&lt;int&gt;('a')
  • 看起来你正在将一个(指向一个)“窄”字符串转换为一个(指向一个)“宽”字符串。请改用正确的函数(以“A”结尾,而不是“W”)或转换(而不是强制转换)您的输入。
  • @BKS 各种口味?只有UuidFromStringWUuidFromStringA两种口味,第二种是正确的,去掉你的演员(RPC_WSTR),你不需要它。

标签: c++ visual-studio boost boost-propertytree


【解决方案1】:

std::string::c_str() 返回一个const char* 指针,您将其类型转换为RPC_WSTR,也就是非const unsigned short*。那个演员永远不会奏效。至少,您需要先将std::string转换为 UTF-16 编码的std::wstring,例如:

#include <locale>
#include <codecvt>

std::wstring widStr = std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>{}.from_bytes(idStr);

auto res = UuidFromStringW(reinterpret_cast<RPC_WSTR>(const_cast<wchar_t*>(widStr.c_str())), &idAsGuid);
// or:
// auto res = UuidFromStringW(reinterpret_cast<RPC_WSTR>(&widStr[0]), &idAsGuid);

否则,请改用UuidFromStringA(),但请注意RPC_CSTR 被定义为非常量 unsigned char*,因此您仍然需要类似的转换:

auto res = UuidFromStringA(reinterpret_cast<RPC_CSTR>(const_cast<char*>(idStr.c_str())), &idAsGuid);
// or:
// auto res = UuidFromStringA(reinterpret_cast<RPC_CSTR>(&idStr[0]), &idAsGuid);

话虽如此,请考虑改用GUIDFromStringA(),这不需要任何转换或转换:

auto res = GUIDFromStringA(idStr.c_str(), &idAsGuid);

不过,您可能需要在 guid 字符串中添加大括号:

auto res = GUIDFromStringA(("{" + idStr + "}").c_str(), &idAsGuid);

否则,只需手动解析guid字符串,如std::istringstreamstd::regexstd::sscanf()等。

【讨论】:

    猜你喜欢
    • 2019-10-10
    • 1970-01-01
    • 1970-01-01
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多