9

I am developing for Windows, I have not found adequate information on how to correctly declare and later on set a unicode string. So far,

wchar_t myString[1024] = L"My Test Unicode String!";

What I assume the above does is [1024] is the allocated string length of how many characters I need to have max in that string. L"" makes sure the string in quotes is unicode (An alt I found is _T()). Now later on in my program when I am trying to set that string to another value by,

myString = L"Another text";

I get compiler errors, what am I doing wrong?

Also if anyone has an easy and in-depth unicode app resource I'd like to have some links, used to have bookmarked a website which was dedicated to that but seems that now is gone.

EDIT

I provide the entire code, I intend to use this as a DLL function but nothing so far is returned.

#include "dll.h"
#include <windows.h>
#include <string>
#include <cwchar>

export LPCSTR ex_test()
{
wchar_t myUString[1024];
std::wcsncpy(myUString, L"Another text", 1024);

int myUStringLength = lstrlenW(myUString);

MessageBoxW(NULL, (LPCWSTR)myUString, L"Test", MB_OK);

int bufferLength = WideCharToMultiByte(CP_UTF8, 0, myUString, myUStringLength, NULL, 0, NULL, NULL);
if (bufferLength <= 0) { return NULL; } //ERROR in WideCharToMultiByte
return NULL;

char *buffer = new char[bufferLength+1];
bufferLength = WideCharToMultiByte(CP_UTF8, 0, myUString, myUStringLength, buffer, bufferLength, NULL, NULL);
if (bufferLength <= 0) { delete[] buffer; return NULL; } //ERROR in WideCharToMultiByte

buffer[bufferLength] = 0;

return buffer;
}
user780756
  • 1,376
  • 3
  • 19
  • 31

2 Answers2

5

The easiest approach is to declare the string differently in the first place:

std::wstring myString;
myString = L"Another text";

If you insist in using arrays of wchar_t directly, you'd use wcscpy() or better wcsncpy() from <cwchar>:

wchar_t myString[1024];
std::wcsncpy(myString, L"Another text", 1024);
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • @Nawaz: I'll make the name consistent. The `1024` is the maximum number of characters to be copied. I don't see in which way the usage of `wcsncpy()` is wrong. If it used `wcscpy()` there would be a chance to copy more characters than there is space. – Dietmar Kühl Sep 28 '13 at 19:40
  • Yes, I verified that. I'm not used to C functions, as I rarely use them. +1 – Nawaz Sep 28 '13 at 19:43
  • Which header(s) do wcscpy() and wcsncpy() need included? – user780756 Sep 28 '13 at 19:46
  • @Nawaz: agreed: that is why there was first `wcscpy()` :-) I noticed an annoying difference to `strncpy()`, though: `wcsncpy(t, s, n)` actually always stores `n` values (possibly zeros). – Dietmar Kühl Sep 28 '13 at 19:46
  • 1
    @user780756: `` (with a `std::` prefix) and `` without (I updated the answer). – Dietmar Kühl Sep 28 '13 at 19:47
  • I tried #include and std::wstring myString; but the compiler says that wstring is not declared. Using MinGW btw. – user780756 Sep 28 '13 at 19:53
  • 1
    @user780756: `std::wstring` is declared in ``. – Dietmar Kühl Sep 28 '13 at 19:54
  • Seems that this part works but it complains that now it is not compatible with lstrlenW() Invalid typecast from wstring to LPCWSTR. – user780756 Sep 28 '13 at 19:59
  • Doesn't `wcsncpy` suffer from the same bad problems as `strncpy` (no null termination on overflow)? – Roddy Sep 28 '13 at 20:12
  • Updated my topic above to reflect my problem on the field. – user780756 Sep 28 '13 at 20:17
  • @Roddy: yes, it does. There doesn't seem to be a better option, though. Hence my recommendation to use `std::wstring`. – Dietmar Kühl Sep 28 '13 at 20:46
  • @DietmarKühl Well, there's strsafe.h on Windows. http://msdn.microsoft.com/en-us/library/windows/desktop/ms647466(v=vs.85).aspx#using But you're right that using C++ strings is the way to go - even if they are far from unicode-friendly. Speaking of which, prefer UTF8 to wstrings.... http://www.utf8everywhere.org/ – Roddy Sep 28 '13 at 21:43
  • @Roddy: I'm really just interested in approaches covered by a platform independant standard (and where I deviate from this view I'm interested in POSIX approaches which is actually still a standard). – Dietmar Kühl Sep 28 '13 at 23:29
  • Visual Studio 2015 tells me that wcsncpy is unsafe, and that I should use wcsncpy_s instead. – Nicolas Raoul Mar 04 '16 at 05:55
4
wchar_t myString[1024] = L"My Test Unicode String!";

is initializing the array like this

wchar_t myString[1024] = { 'M', 'y', ' ', ..., 'n', 'g', '!', '\0' };

but

myString = L"Another text";

is an assignment which u cannot do to arrays. u have to copy the contents of the new string into your old array:

const auto& newstring = L"Another text";
std::copy(std::begin(newstring), std::end(newstring), myString);

or if its a pointer

wchar_t* newstring = L"Another text";
std::copy(newstring, newstring + wsclen(newstring) + 1, myString);

or as nawaz suggested with copy_n

std::copy_n(newstring, wsclen(newstring) + 1, myString);
Evelyn
  • 3
  • 4
Kal
  • 1,309
  • 11
  • 16