For example,
const char* bytes = "somemultibytecharacter一些宽字符";
size_t n = strlen(bytes);
How to convert bytes to FString or TCHAR* in Unreal Engine C++ code?
I know I can convert with std::mbstowcs or MultiByteToWideChar, but I'm trying to find a UE4 alternative.
Just use FString(int32 InCount, const CharType* InSrc).
Usage:
const char* bytes = "somemultibytecharacter一些宽字符";
size_t n = strlen(bytes);
const FString& Str = FString(n, bytes);
const TCHAR* Text = *Str;
Note, in my copy of Unreal Engine 4, TCHAR is wchar_t:
typedef wchar_t WIDECHAR;
typedef WIDECHAR TCHAR
Related
I have the following wstring:
std::wstring testVal("Test");
Which I need to place inside this value:
static const TCHAR* s_test_val;
So far I have tried:
static const TCHAR* s_test_val = (const wchar_t*) testVal.c_str();
static const TCHAR* s_test_val = (wchar_t*) testVal.c_str();
static const TCHAR* s_test_val = (TCHAR*) testVal.c_str();
static const TCHAR* s_test_val = (TCHAR*) testVal;
But without success; s_test_val keeps appearing as an empty string.
static const TCHAR* s_test_val = testVal.c_str();
This one is correct on the condition that UNICODE is defined in which case TCHAR will be an alias of wchar_t.
If UNICODE isn't defined, then you would need to perform some conversion, but it might not be worth the effort to support non-unicode builds. Your attempt that uses a cast would silently do the wrong thing in that case while this one safely produces an error.
In case you don't care about non-unicode support (and I cannot think of a reason why anyone would), then I recommend minimising the use of TCHAR entirely.
Don't use TCHAR unless Windows 9x support is essential. Additionally, your static pointer pointing to an automatic variable is very suspicious. You either want:
static wchar_t constexpr const* s_test_val = L"Test";
or
std::wstring testVal = L"Test";
wchar_t const* s_test_val = testVal.c_str();
or
std::wstring testVal = L"Test";
auto const s_test_val = testVal.c_str();
As the title states I have a simple char that retrieves a full path name of a file I am looking for and I need to convert it to const wchar_t. How can I achieve this? Here is an example of the code:
int main()
{
char filename[] = "poc.png";
char fullFilename[MAX_PATH];
GetFullPathName(filename, MAX_PATH, fullFilename, nullptr);
const wchar_t *path = fullFilename;
}
As you can see I am trying to get the filename to convert but I couldn't find a way to do so. What would be the most simple solution to this?
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.
as the question says, what would be a suitable template function to convert wstring to const char *? My program is written entirely in Unicode, however, SQlite requires const char * for most of their functions.
I found the method of doing this on msdn, here: http://msdn.microsoft.com/en-us/library/ms235631%28v=vs.80%29.aspx, where name is a wstring.
// Convert to a char*
size_t origsize = wcslen(name.c_str()) + 1;
const size_t newsize = 100;
size_t convertedChars = 0;
char nstring[newsize];
wcstombs_s(&convertedChars, nstring, origsize, name.c_str(), _TRUNCATE);
You should use the *16 sqlite functions (e.g. sqlite3_prepare16) where you4 can give UTF-16 (i.e. wstring) as parameters. Don_t forget to use 2*wcslen as length of the string. If you insist on the const char* functions, you have to convert to UTF-8 first.
How can I convert std::wstring to const *char in C++?
You can convert a std::wstring to a const wchar_t * using the c_str member function :
std::wstring wStr;
const wchar_t *str = wStr.c_str();
However, a conversion to a const char * isn't natural : it requires an additional call to std::wcstombs, like for example:
#include <cstdlib>
// ...
std::wstring wStr;
const wchar_t *input = wStr.c_str();
// Count required buffer size (plus one for null-terminator).
size_t size = (wcslen(input) + 1) * sizeof(wchar_t);
char *buffer = new char[size];
#ifdef __STDC_LIB_EXT1__
// wcstombs_s is only guaranteed to be available if __STDC_LIB_EXT1__ is defined
size_t convertedSize;
std::wcstombs_s(&convertedSize, buffer, size, input, size);
#else
std::wcstombs(buffer, input, size);
#endif
/* Use the string stored in "buffer" variable */
// Free allocated memory:
delete buffer;
You cannot do this just like that. std::wstring represents a string of wide (Unicode) characters, while char* in this case is a string of ASCII characters. There has to be a code page conversion from Unicode to ASCII.
To make the conversion you can use standard library functions such as wcstombs, or Windows' WideCharToMultiByte function.
Updated to incorporate information from comments, thanks for pointing that out.
I have a string in char* format and would like to convert it to wchar_t*, to pass to a Windows function.
Does this little function help?
#include <cstdlib>
int mbstowcs(wchar_t *out, const char *in, size_t size);
Also see the C++ reference
If you don't want to link against the C runtime library, use the MultiByteToWideChar API call, e.g:
const size_t WCHARBUF = 100;
const char szSource[] = "HELLO";
wchar_t wszDest[WCHARBUF];
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szSource, -1, wszDest, WCHARBUF);
the Windows SDK specifies 2 functions in kernel32.lib for converting strings from and to a wide character set. those are MultiByteToWideChar() and WideCharToMultiByte().
please note that, unlike the function name suggest, the string does not necessarily use a multi-byte character set, but can be a simple ANSI string. alse note that those functions understand UTF-7 and UTF-8 as a multi-byte character set. the wide char character set is always UTF-16.
schnaader's answer use the conversion defined by the current C locale, this one uses the C++ locale interface (who said that it was simple?)
std::wstring widen(std::string const& s, std::locale loc)
{
std::char_traits<wchar_t>::state_type state = { 0 };
typedef std::codecvt<wchar_t, char, std::char_traits<wchar_t>::state_type >
ConverterFacet;
ConverterFacet const& converter(std::use_facet<ConverterFacet>(loc));
char const* nextToRead = s.data();
wchar_t buffer[BUFSIZ];
wchar_t* nextToWrite;
std::codecvt_base::result result;
std::wstring wresult;
while ((result
= converter.in
(state,
nextToRead, s.data()+s.size(), nextToRead,
buffer, buffer+sizeof(buffer)/sizeof(*buffer), nextToWrite))
== std::codecvt_base::partial)
{
wresult.append(buffer, nextToWrite);
}
if (result == std::codecvt_base::error) {
throw std::runtime_error("Encoding error");
}
wresult.append(buffer, nextToWrite);
return wresult;
}