4

I have gotten a WCHAR[MAX_PATH] from (PROCESSENTRY32) pe32.szExeFile on Windows. The following do not work:

std::string s;
s = pe32.szExeFile; // compile error. cast (const char*) doesnt work either

and

std::string s;
char DefChar = ' ';
WideCharToMultiByte(CP_ACP,0,pe32.szExeFile,-1, ch,260,&DefChar, NULL);
s = pe32.szExeFile;
user1334943
  • 127
  • 1
  • 1
  • 10
  • 6
    Do you really need it as a `std::string`? It should convert directly to a `std::wstring`, as in `std::wstring s(pe32.szExeFile);` – Jerry Coffin Apr 18 '12 at 06:44

4 Answers4

3

For your first example you can just do:

std::wstring s(pe32.szExeFile);

and for second:

char DefChar = ' ';
WideCharToMultiByte(CP_ACP,0,pe32.szExeFile,-1, ch,260,&DefChar, NULL);
std::wstring s(pe32.szExeFile);

as std::wstring has a char* ctor

EdChum
  • 376,765
  • 198
  • 813
  • 562
  • Neither work same error. error: C2664: 'std::basic_string<_Elem,_Traits,_Ax>::basic_string(std::basic_string<_Elem,_Traits,_Ax>::_Has_debug_it)' : cannot convert parameter 1 from 'WCHAR [260]' to 'std::basic_string<_Elem,_Traits,_Ax> – user1334943 Apr 18 '12 at 06:47
  • sorry should've used wstring version, should compile now – EdChum Apr 18 '12 at 06:48
  • @user1334943 does it work with `std::wstring s(&pe32.szExeFile)`? – EdChum Apr 18 '12 at 07:00
2

Your call to WideCharToMultiByte looks correct, provided ch is a sufficiently large buffer. After than, however, you want to assign the buffer (ch) to the string (or use it to construct a string), not pe32.szExeFile.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
2

There are convenient conversion classes from ATL; you may want to use some of them, e.g.:

std::string s( CW2A(pe32.szExeFile) );

Note however that a conversion from Unicode UTF-16 to ANSI can be lossy. If you wan't a non-lossy conversion, you could convert from UTF-16 to UTF-8, and store UTF-8 inside std::string.

If you don't want to use ATL, there are some convenient freely available C++ wrappers around raw Win32 WideCharToMultiByte to convert from UTF-16 to UTF-8 using STL strings.

1
#ifndef __STRINGCAST_H__
#define __STRINGCAST_H__

#include <vector>
#include <string>
#include <cstring>
#include <cwchar>
#include <cassert>

template<typename Td>
Td string_cast(const wchar_t* pSource, unsigned int codePage = CP_ACP);

#endif // __STRINGCAST_H__

template<>
std::string string_cast( const wchar_t* pSource, unsigned int codePage )
{
    assert(pSource != 0);
    size_t sourceLength = std::wcslen(pSource);
    if(sourceLength > 0)
    {
        int length = ::WideCharToMultiByte(codePage, 0, pSource, sourceLength, NULL, 0, NULL, NULL);
        if(length == 0)
            return std::string();

        std::vector<char> buffer( length );
        ::WideCharToMultiByte(codePage, 0, pSource, sourceLength, &buffer[0], length, NULL, NULL);

        return std::string(buffer.begin(), buffer.end());
    }
    else
        return std::string();

}

and use this template as followed

PWSTR CurWorkDir;
std::string CurWorkLogFile;

CurWorkDir = new WCHAR[length];

CurWorkLogFile = string_cast<std::string>(CurWorkDir);

....


delete [] CurWorkDir;