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

31,586

Solution 1

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);

Solution 2

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);
Share:
31,586
user780756
Author by

user780756

Updated on July 25, 2022

Comments

  • user780756
    user780756 almost 2 years

    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;
    }
    
  • Dietmar Kühl
    Dietmar Kühl over 10 years
    @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.
  • Nawaz
    Nawaz over 10 years
    Yes, I verified that. I'm not used to C functions, as I rarely use them. +1
  • user780756
    user780756 over 10 years
    Which header(s) do wcscpy() and wcsncpy() need included?
  • Dietmar Kühl
    Dietmar Kühl over 10 years
    @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).
  • Nawaz
    Nawaz over 10 years
    wchar_t (&newstring)[] = L"Another text"; should not compile.
  • Dietmar Kühl
    Dietmar Kühl over 10 years
    @user780756: <cwchar> (with a std:: prefix) and <wchar.h> without (I updated the answer).
  • Kal
    Kal over 10 years
    @Nawaz i think i fixed it
  • user780756
    user780756 over 10 years
    I tried #include <cwchar> and std::wstring myString; but the compiler says that wstring is not declared. Using MinGW btw.
  • Dietmar Kühl
    Dietmar Kühl over 10 years
    @user780756: std::wstring is declared in <string>.
  • Nawaz
    Nawaz over 10 years
    BTW, for the last case : std::copy_n(newstring, wsclen(newstring)+1, myString); reads better.
  • user780756
    user780756 over 10 years
    Seems that this part works but it complains that now it is not compatible with lstrlenW() Invalid typecast from wstring to LPCWSTR.
  • Roddy
    Roddy over 10 years
    Doesn't wcsncpy suffer from the same bad problems as strncpy (no null termination on overflow)?
  • user780756
    user780756 over 10 years
    Updated my topic above to reflect my problem on the field.
  • Dietmar Kühl
    Dietmar Kühl over 10 years
    @Roddy: yes, it does. There doesn't seem to be a better option, though. Hence my recommendation to use std::wstring.
  • Roddy
    Roddy over 10 years
    @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.org
  • Dietmar Kühl
    Dietmar Kühl over 10 years
    @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).
  • Nicolas Raoul
    Nicolas Raoul about 8 years
    Visual Studio 2015 tells me that wcsncpy is unsafe, and that I should use wcsncpy_s instead.