How to declare wchar_t and set its string value later on?
Asked Answered
J

2

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;
}
Jackhammer answered 28/9, 2013 at 19:29 Comment(0)
F
6

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);
Fatigued answered 28/9, 2013 at 19:34 Comment(14)
@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.Sylvester
Yes, I verified that. I'm not used to C functions, as I rarely use them. +1Personalize
Which header(s) do wcscpy() and wcsncpy() need included?Jackhammer
@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).Sylvester
@user780756: <cwchar> (with a std:: prefix) and <wchar.h> without (I updated the answer).Sylvester
I tried #include <cwchar> and std::wstring myString; but the compiler says that wstring is not declared. Using MinGW btw.Jackhammer
@user780756: std::wstring is declared in <string>.Sylvester
Seems that this part works but it complains that now it is not compatible with lstrlenW() Invalid typecast from wstring to LPCWSTR.Jackhammer
Doesn't wcsncpy suffer from the same bad problems as strncpy (no null termination on overflow)?Ejection
Updated my topic above to reflect my problem on the field.Jackhammer
@Roddy: yes, it does. There doesn't seem to be a better option, though. Hence my recommendation to use std::wstring.Sylvester
@DietmarKühl Well, there's strsafe.h on Windows. msdn.microsoft.com/en-us/library/windows/desktop/… 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.... utf8everywhere.orgEjection
@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).Sylvester
Visual Studio 2015 tells me that wcsncpy is unsafe, and that I should use wcsncpy_s instead.Celie
A
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);
Aboveground answered 28/9, 2013 at 19:34 Comment(2)
wchar_t (&newstring)[] = L"Another text"; should not compile.Personalize
BTW, for the last case : std::copy_n(newstring, wsclen(newstring)+1, myString); reads better.Personalize

© 2022 - 2024 — McMap. All rights reserved.