How to Convert Char* to Wchar_T*

How to convert char* to wchar_t*?

Use a std::wstring instead of a C99 variable length array. The current standard guarantees a contiguous buffer for std::basic_string. E.g.,

std::wstring wc( cSize, L'#' );
mbstowcs( &wc[0], c, cSize );

C++ does not support C99 variable length arrays, and so if you compiled your code as pure C++, it would not even compile.

With that change your function return type should also be std::wstring.

Remember to set relevant locale in main.

E.g., setlocale( LC_ALL, "" ).

How to convert char to wchar_t*?

Your code doesn't show any need to convert between char and wchar_t. Most likely you don't actually need to convert the character types. If you want to use the wchar_t-friendly GetFullPathNameW, then just use wchar_t instead of char.

int main()
{
wchar_t fullFilename[MAX_PATH];
GetFullPathNameW(L"poc.png", MAX_PATH, fullFilename, nullptr);
const wchar_t *path = fullFilename;
return 0;
}

If you really do need to convert between wchar_t-based C-style strings and char-based C-style strings, then you can use the APIs MultiByteToWideChar and WideCharToMultiByte.

how to convert char array to wchar_t array?

From MSDN:

#include <iostream>
#include <stdlib.h>
#include <string>

using namespace std;
using namespace System;

int main()
{
char *orig = "Hello, World!";
cout << orig << " (char *)" << endl;

// Convert to a wchar_t*
size_t origsize = strlen(orig) + 1;
const size_t newsize = 100;
size_t convertedChars = 0;
wchar_t wcstring[newsize];
mbstowcs_s(&convertedChars, wcstring, origsize, orig, _TRUNCATE);
wcscat_s(wcstring, L" (wchar_t *)");
wcout << wcstring << endl;
}

C++ - Converting a char to wchar_t. Getting a segfault

Stepping through the code to give OP a look at what's going on and why it won't work. Then we'll take a look at a method to do what they want that is as close as possible to their intent. Then a hint on how to do this a bit better in the C++ world.

wchar_t read(istream &stream) {
char *c;

Declares a pointer c and doesn't point it at anything. c is an uninitialized variable. Think of it like being invited to Steve's house for a party, but no one told you where he lived. Odds are very good that where ever you go, it won't be Steve's house.

 stream.read(c, sizeof(*c));

sizeof(*c) will return the size of one character. Probably 8 bits and 1 byte, but c still hasn't been pointed at anything so this is Undefined Behaviour. There is no telling what the program will do, but most likely it reads one byte into some unknown space in memory. Maybe this causes a crash because you can't write there. Maybe it writes over something that it is allowed to write over and screws up something else.

 cout << *c << endl;

Tries to print out c. If the program survived the read above, odds are good it will survive this as well, but this is also Undefined Behaviour.

 wchar_t retChar = static_cast<wchar_t>(*c);

This will literally stuff one character's worth of data into a wide character. It will not convert it according to locale or any other character encoding. char is a numeric code that has been defined to be interpreted as a character. A cast will stupidly put the character value, say 'A' and ASCII encoding into retChar. retChar now equals 65. 65 could mean anything depending on the encoding used by wchar_t. It might still mean 'A', but sorry Ayn Rand, this is one case where A may well not be A.

 return retChar;
}

To do what OP was trying to do (and ignoring that there are better ways to do this for the time being):

#include <iostream>
using namespace std;
wchar_t read(istream &stream) {
char c[2];

Allocates an array of characters. Why? because the easiest way I know of is to do the conversion on a string.

 stream.read(c, sizeof(c[0]));

c is now an array which decays to a pointer. We only want to read one char, so sizeof(c[0]) gets the size of the first element in the array.

 c[1] = '\0';
cout << c << endl;

Null terminate and print.

 wchar_t retChar[2];

Again, an array.

 mbstowcs(retChar, c, 1);

convert one character from char to wide char using whatever locale has been set. Read more on locales here: http://en.cppreference.com/w/cpp/locale/setlocale

And documentation on mbstowcs: http://en.cppreference.com/w/cpp/string/multibyte/mbstowcs

 return retChar[0];
}

Put all together with a quick tester:

#include <iostream>
#include <cstdlib>

wchar_t read(std::istream &stream)
{
char c[2];
stream.read(c, sizeof(c[0]));
c[1] = '\0';
std::cout << c << std::endl;
wchar_t retChar[2];
mbstowcs(retChar, c, 1);
return retChar[0];
}

int main()
{
std::wcout << read(std::cin) << std::endl;
}

This is simple, but ugly in the C++ world where you should stick to strings where possible. In that case look into std::wstring_convert.

Convert const char* to const wchar_t*

There are multiple questions on SO that address the problem on Windows. Sample posts:

  1. char* to const wchar_t * conversion
  2. conversion from unsigned char* to const wchar_t*

There is a platform agnostic method posted at http://ubuntuforums.org/showthread.php?t=1579640. The source from this site is (I hope I am not violating any copyright):

#include <locale>
#include <iostream>
#include <string>
#include <sstream>
using namespace std ;

wstring widen( const string& str )
{
wostringstream wstm ;
const ctype<wchar_t>& ctfacet = use_facet<ctype<wchar_t>>(wstm.getloc()) ;
for( size_t i=0 ; i<str.size() ; ++i )
wstm << ctfacet.widen( str[i] ) ;
return wstm.str() ;
}

string narrow( const wstring& str )
{
ostringstream stm ;

// Incorrect code from the link
// const ctype<char>& ctfacet = use_facet<ctype<char>>(stm.getloc());

// Correct code.
const ctype<wchar_t>& ctfacet = use_facet<ctype<wchar_t>>(stm.getloc());

for( size_t i=0 ; i<str.size() ; ++i )
stm << ctfacet.narrow( str[i], 0 ) ;
return stm.str() ;
}

int main()
{
{
const char* cstr = "abcdefghijkl" ;
const wchar_t* wcstr = widen(cstr).c_str() ;
wcout << wcstr << L'\n' ;
}
{
const wchar_t* wcstr = L"mnopqrstuvwx" ;
const char* cstr = narrow(wcstr).c_str() ;
cout << cstr << '\n' ;
}
}

Convert char to wchar_t using standard library?

It does in the header wchar.h. It is called btowc:

The btowc function returns WEOF if c has the value EOF or if (unsigned char)c
does not constitute a valid single-byte character in the initial shift state. Otherwise, it
returns the wide character representation of that character.

Cannot convert ‘char**’ to ‘wchar_t**’

This API is part of python 3.0 and above and in my knowledge, there's no easy way to get this done. However, I think, you can try converting the argv to a w_char ** and then call PySys_SetArgv(). mbstowcs() may come handy in this case.

For example, some pseudo-code (not tested) will look like

wchar_t **changed_argv;

changed_argv = malloc((argc)* sizeof*changed_argv);

for (int i = 0; i < argc, i++)
{
changed_argv[i] = malloc(strlen(argv[i]) + 1);
mbstowcs(changed_argv[i], argv[i], strlen(argv[i]) + 1);
}


Related Topics



Leave a reply



Submit