简体   繁体   中英

HowTo compare std::wstring & char*?

What I have:

  • [wstr1] 1 std::wstring value (eg "(GMT+04:30) Kabul")
  • [str2] 1 char* filled with the same data as std::wstring (with the same text)

I'm simply trying to compare this two value - but the following code doesn't appear to work. KMP.

Here is the converter from char* to std::wstring,

std::wstring TimeZone::TimeZone::char2ws(const char* src)
{
    /* Convert to a wchar_t*
     * http://msdn.microsoft.com/en-us/library/ms235631(v=vs.80).aspx
     */

    // Convert to a wchar_t*
    size_t origsize = strlen(src) + 1;
    const size_t newsize = 512;
    size_t convertedChars = 0;
    wchar_t wcstring[newsize];
    mbstowcs_s(&convertedChars, wcstring, origsize, src, _TRUNCATE);

    return wcstring;
}

after that I made simple compare with

// wstr1 is std::wstring, with "(GMT+04:30) Kabul" string
// wstr2 = char2ws(str2), 
return (wstr1 == wstr2);

And no luck. String in VSVC2008 IDE debugger are visually equal.

Question : why do compare method gives me false always?

Thanks.


Solution : great thanks to Alexandre C.

bool weirdEquals(const std::wstring& str, char const* c)
{
    std::string c_str(c);
    if (str.size() < c_str.size())
    {
        return false;
    }
    return std::equal(c_str.begin(), c_str.end(), str.begin());
}

PS. I made some changes.

To compare strings, you need to compare them via the same character set. wchar_t and char are clearly using different character sets so you cannot compare them using a typical char-for-char string comparison.

Typically, you would convert the char* string to a wchar_t* string (using mbtowcs or MultiByteToWideChar ) so you can compare them both as Unicode strings, as you are doing.

But I suspect in your case though, you only ever expect simple ASCII characters to match, in which case you can do a char-by-char comparison, comparing wchar_t s to char s. Note: do not use a cast to do this.

As to why your conversion is not working, see @Erik's answer.

Compare like this, if you're sure that you have only ASCII characters. Otherwise, you can pass a custom (locale dependant ?) comparer to std::equal .

bool weirdEquals(char const* c, size_t n, const std::wstring& str)
{
    if (str.size() < n) return false;
    return std::equal(c, c + n, str.begin());
}

You need to pass newsize , not origsize , to mbstowcs_s.

Also, consider using:

wchar_t wcstring[newsize] = { 0 };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM