将字符串转换为 GUID 不会给出正确的结果
casting a string to a GUID does not give right result
在我的程序中,我需要读取存储在 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-CCCCCCCCCCCCCC)。我哪里错了?
std::string::c_str()
returns 一个 const char*
指针,您正在将其类型转换为 RPC_WSTR
,又名 非常量 unsigned short*
。那个演员永远不会奏效。最起码,你需要先convert the std::string
to UTF-16 encoded std::wstring
, eg:
#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::istringstream
、std::regex
、std::sscanf()
等
在我的程序中,我需要读取存储在 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-CCCCCCCCCCCCCC)。我哪里错了?
std::string::c_str()
returns 一个 const char*
指针,您正在将其类型转换为 RPC_WSTR
,又名 非常量 unsigned short*
。那个演员永远不会奏效。最起码,你需要先convert the std::string
to UTF-16 encoded std::wstring
, eg:
#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::istringstream
、std::regex
、std::sscanf()
等