WideCharToMultiByte not working for the non-english string

prxy 61 Reputation points
2022-01-05T06:18:49.703+00:00

Hi,

I'm trying to convert the Unicode (non-english) string to multibyte. Just to be safe, I'm converting the string again to Unicode form multibyte and comparing the strings (input string and input string(Unicode)--> multibyte --> Unicode ) I'm using wcscmp API to compare the string, but comparison fails. This works fine for English strings. Below is sample program.

    #include <iostream>
    #include<Windows.h>
    #include <atlstr.h>
    #include <string>

    using namespace std;
    typedef wchar_t MYUCHAR;

    namespace conversion
    {

     static HRESULT UniToChar(char** ppDstBuf, wchar_t const* pUniBuf, int& iDstBytes, UINT cp = CP_ACP)
     {
     HRESULT hRet = S_OK;

     if (nullptr == ppDstBuf || nullptr == pUniBuf)
     return HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);

     int iMultiBufSize = WideCharToMultiByte(cp, 0, pUniBuf, -1, nullptr, 0, nullptr, nullptr);
     if (0 == iMultiBufSize)
     {
     hRet = HRESULT_FROM_WIN32(GetLastError());
     return hRet;
     }
     try
     {
     *ppDstBuf = new char[static_cast<size_t>(iMultiBufSize)];
     }
     catch (std::bad_alloc&)
     {
     hRet = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
     return hRet;
     }
     if (nullptr == *ppDstBuf)
     {
     hRet = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
     return hRet;
     }
     if (0 == WideCharToMultiByte(cp, 0, pUniBuf, -1, *ppDstBuf, iMultiBufSize, nullptr, nullptr))
     {
     hRet = HRESULT_FROM_WIN32(GetLastError());
     delete[] * ppDstBuf;
     *ppDstBuf = nullptr;
     return hRet;
     }
     iDstBytes = iMultiBufSize;

     return hRet;
     }


     static HRESULT CharToUni(MYUCHAR** ppDstUniBuf, char const* pBuf, int& iDstUniChBufSz, UINT cp = CP_ACP)
     {
     HRESULT hRet = S_OK;
     iDstUniChBufSz = 0;
     if (nullptr == pBuf || nullptr == ppDstUniBuf)
     return HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);

     int iUniBufSize = MultiByteToWideChar(cp, 0, pBuf, -1, nullptr, 0);
     if (0 == iUniBufSize)
     {
     hRet = HRESULT_FROM_WIN32(GetLastError());
     return hRet;
     }
     try
     {
     *ppDstUniBuf = new MYUCHAR[static_cast<size_t>(iUniBufSize)];
     }
     catch (std::bad_alloc&)
     {
     hRet = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
     return hRet;
     }
     if (nullptr == *ppDstUniBuf)
     {
     hRet = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
     return hRet;
     }
     if (0 == MultiByteToWideChar(cp, 0, pBuf, -1, *ppDstUniBuf, iUniBufSize))
     {
     hRet = HRESULT_FROM_WIN32(GetLastError());
     delete[] * ppDstUniBuf;
     *ppDstUniBuf = nullptr;
     }
     iDstUniChBufSz = iUniBufSize;

     return hRet;
     }
    };
    static HRESULT UnicodeToChar(char** ppDstBuf, MYUCHAR const* pUniBuf, int& iDstBytes, UINT cp = CP_ACP)
    {
     HRESULT hRet = S_OK;
     hRet = conversion::UniToChar(ppDstBuf, pUniBuf, iDstBytes, cp);
     if (FAILED(hRet))
     return hRet;
     MYUCHAR* pUChar = nullptr;
     int iUniBufSz = 0;

     hRet = conversion::CharToUni(&pUChar, *ppDstBuf, iUniBufSz, cp);
     if (FAILED(hRet))
     return hRet;

     if (pUChar)
     {
     if (wcscmp(pUChar, pUniBuf))
     hRet = E_FAIL;
     delete[] pUChar;
     }
     return hRet;
    }

    int main()
    {

     char* pChar;
     std::wstring unifilePath = L"E:\\第三期中期.txt";
     int iLen = 0;
     HRESULT hRet = UnicodeToChar(&pChar, unifilePath.c_str(), iLen, CP_ACP);
     if(FAILED(hr))
    {
     \\ cout 
    }

    return 0;
}

Any idea, what could have gone wrong.
Thanks

Visual Studio
Visual Studio
A family of Microsoft suites of integrated development tools for building applications for Windows, the web and mobile devices.
4,606 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,527 questions
Visual Studio Debugging
Visual Studio Debugging
Visual Studio: A family of Microsoft suites of integrated development tools for building applications for Windows, the web and mobile devices.Debugging: The act or process of detecting, locating, and correcting logical or syntactical errors in a program or malfunctions in hardware. In hardware contexts, the term troubleshoot is the term more frequently used, especially if the problem is major.
939 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Minxin Yu 10,031 Reputation points Microsoft Vendor
    2022-01-05T08:44:50.267+00:00

    Hi, @prxy

    I tested WideCharToMultiByte and it works well. You could refer to the snippet below:

    #include<iostream>  
    #include<Windows.h>  
    using namespace std;  
    int main()  
    {  
        std::wstring sBuf = L"E:\\第三期中期.txt";  
        DWORD dBufSize = WideCharToMultiByte(CP_ACP, 0, sBuf.c_str(), -1, NULL, 0, NULL, FALSE);  
        char* dBuf = new char[dBufSize];  
        memset(dBuf, 0, dBufSize);   
        int nRet = WideCharToMultiByte(CP_ACP, 0, sBuf.c_str(), -1, dBuf, dBufSize, NULL, FALSE);  
        cout << dBuf;  
        delete[]dBuf;  
        return 0;  
    }  
    

    Best regards,

    Minxin Yu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

  2. RLWA32 40,286 Reputation points
    2022-01-05T09:07:24.04+00:00

    Round-tripping does not work because the code page (CP_ACP) used by WideCharToMultiByte is incapable of mapping the non-english unicode characters and so the default character ("?") is used to produce the resulting string. Consequently, converting this result back to unicode does not produce the original string.

    0 comments No comments