【问题标题】:How to properly convert char* into std::string? (issues while using expat / std::string(char*))如何正确地将 char* 转换为 std::string? (使用 expat / std::string(char*) 时的问题)
【发布时间】:2011-07-21 12:51:47
【问题描述】:

问题描述

我正在将 Expat 与自定义 C++ 包装器一起使用,我已经在其他项目中对其进行了测试。 我遇到了问题,因为原始数据(c_str)没有以正确的方式转换为 std::string。这让我很担心,因为我没有更改包装器的来源。

在此转换后,字符串似乎获得了以空字符结尾的字符:

onCharacterData( std::string( pszData, nLength ) ) // --> std::string( char* pszData)

我该如何解决这个问题?

自己的外籍人士包装

// Wrapper defines the class Expat and implements for example:
void XMLCALL Expat::CharacterDataHandler( void *pUserData, const XML_Char *pszData,
                                          int nLength )
{
  Expat* pThis = static_cast<Expat*>( pUserData );

  // XML_Char is char, therefore this call contains i.e.: std::string("hello", 5) 
  pThis->onCharacterData( std::string( pszData, nLength ) );
}

自定义解析器

// Parser is defined as: class Parser : Expat
void Parser::onCharacterData(const std::string& data )
{
  // data is no longer char*, but a std::string.
  // It seems to contain \0 after each character which is wrong!

  // [...]
}

expat 包装器中的字符数据 (char*)

解析器中的字符数据(std::string)

【问题讨论】:

  • 你可以说std::string(pszData);有一个以空结尾的 C 字符串的构造函数。
  • @Kerrek: .. 这在这里行不通! (很偶然)
  • 我已经试过了。不幸的是,这不起作用。
  • 耻辱。 “psz”通常表示“空终止”!

标签: c++ string expat-parser null-terminated


【解决方案1】:

您的 pszData 似乎是某种特定于实现的 Unicode 派生格式,其中每个“字符”占用两个 chars。

这意味着源数据已损坏;也许它应该是一个wchar_t 缓冲区。

【讨论】:

  • 这将解释屏幕截图中的结果,但恐怕这不是这里的情况。活动定义是:typedef char XML_Char; 因此 std::string( char* ) 应该可以工作。
  • @Smamatti:这并没有说明缓冲区是如何填充的。有人占用了char 缓冲区,并用不应在char 缓冲区中的数据填充它。您在其他地方说过 UTF-8 编码是有效的;我想这就是你的答案。事实上,std::string 包含与您的源数据相同的表示,所以这里没有错误。
  • 我使用的是 libexpatwMT.dll 而不是 libexpatMT.dll。您最初对 UTF-16 编码字符串的想法是正确的。更改标题/宏当然不会改变任何东西。感谢您将我引向正确的方向。
【解决方案2】:

看起来外籍人士正在使用宽字符和/或 UTF-16。在回来的路上尝试使用std::wstring

编辑我在文档中发现如果定义了 XML_UNICODEXML_UNICODE_WCHAR_T 宏,它正在使用 wchar_t

【讨论】:

  • 确实,这些宏确定了 XML_CHAR 的 typedef,但不幸的是,未设置宏并且 Visual Studio 确认,XML_CHARchar 类型和 UTF-8 编码的。
【解决方案3】:

正如其他人指出的那样,pszData 似乎是一个多字节字符串。您应该尝试使用std::basic_string&lt;XML_Char&gt; 代替std::stringstd::wstring。如果看起来太冗长,请使用typedef

当然,如果XML_Char 既不是char 也不是wchar_t,您可能需要为std::char_traits 提供模板特化

编辑:
一些谷歌搜索显示 XML_Char 是 UTF-8;如果您定义 XML_UNICODEXML_UNICODE_WCHAR_T,则可以使该库使用 UTF-16。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 2013-07-18
    • 1970-01-01
    • 1970-01-01
    • 2017-03-10
    • 2016-06-10
    相关资源
    最近更新 更多