如何正确地将char *转换为std :: string? (使用expat / std :: string(char *)时出现问题)

时间:2011-07-21 12:51:47

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

问题描述

我正在使用带有自定义C ++包装器的Expat,我已经在其他项目上测试过了。 我遇到了问题,因为原始数据(c_str)没有以正确的方式转换为std :: string。这让我很难过,因为我没有改变包装器的来源。

在此转换之后,字符串看起来像是以空字符结尾的字符:

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

我该如何解决这个问题?

拥有expat包装器

// 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 *)

中的字符数据

Character data within the expat wrapper (char*)

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

Character data within the parser (std::string)

3 个答案:

答案 0 :(得分:5)

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

这意味着源数据被破坏;它可能应该是wchar_t缓冲区。

答案 1 :(得分:2)

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

编辑我在文档中发现,如果定义了wchar_tXML_UNICODE宏,则会使用XML_UNICODE_WCHAR_T

答案 2 :(得分:0)

正如其他人所指出的,pszData似乎是一个多字节字符串。您应该尝试使用std::basic_string<XML_Char>代替std::stringstd::wstring。如果看起来过于冗长,请使用typedef

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

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