Convert std::wstring to WCHAR array - c++

I have been searching the internet for days about this question. I have made a win32 project in which I want to convert a wstring to a WCHAR array
Please give an example
If you find out any mistakes please give an example
wstring timeNow = L"Hello";
WCHAR timeWchar[6] = {(WCHAR)timeNow.c_str()}; // Not Working
Instead of the text I see only a square when I run my program

I assume that by WCHAR, you mean wchar_t.
You can loop over the array and assign the elements.
Or if you don't feel like writing the loop yourself, you can use an algorithm from the standard library. Example:
assert(timeNow.size() < 6);
wchar_t timeWchar[6] {};
std::ranges::copy(timeNow, timeWchar);

You can't really initialize an array with a pointer.
This is closer to what you want without making a copy of the string into an array. just use a pointer to reference the chars.
wstring timeNow = L"Hello";
const WCHAR* timeWchar = timeNow.c_str();
99% of the time, the above works for whatever you need to do assuming you don't need to modify the chars.
If really need to make a make a copy of the characters into a different array, such as when you need to manipulate the string, this will do in Windows just fine - assuming you have a fixed size array that is big enough to receive the copy.
wstring timeNow = L"Hello";
WCHAR timeWchar[6];
StringCchCopyW(timeWchar, ARRAYSIZE(timeWchar), timeNow.c_str());
If you don't know the length ahead of time, then you'll need to allocate it before making the copy:
size_t allocSize = timeNow.size() + 1;
WCHAR timeWchar = new WCHAR[allocSize];
StringCchCopyW(timeWchar, allocSize, timeNow.c_str());
/* don't forget to `delete [] timeWchar` when you are done */
But then again why mess with new and delete when you can just let C++ do the work for you. Make a copy of the string and then use a pointer to reference the characters in the copy.
wstring timeNowCopy = timeNow;
const WCHAR* timeWchar = timeNowCopy.c_str(); // timeWchar points to the array copied into timeNowCopy.
If you can maintain the lifetime of timeNowCopy and timeWchar on the stack together, then you don't need to explicitly new or delete anything.

just do its .data() .
WCHAR timeWchar[6] = ...
wont work anyway
in which I want to convert a wstring to a WCHAR array
if you mean wchar_t [6] type - you just do not need this.
you don't have a situation where you can go with wchar_t [6] but can't with wstr.data() .

Related

Convert dlang char/wchar to string/wstring

How do I convert a single char/wchar to a single-character string/wstring in d? I can't find anything online that doesn't talk about char* or wchar*.
As strings are just immutable(char)[], you can construct them like any other array with chars:
char a = 'a';
string s = [a];
There's a few different options. One is to get a pointer by just taking the address of it. You generally shouldn't use this but you should be aware it is possible.
char a = 'a';
char[] b = (&a)[0 .. 1]; // &a gets a pointer, [0..1] slices the single element
string c = b.idup; // copy it into a new string
If you used a wchar you could get a wstring out of it this way. Then std.conv.to can convert between string and wstring.
Speaking of std.conv.to, that's the next option and is actually the easiest:
import std.conv;
char a = 'a'; // or wchar
string b = to!string(a); // or to!wstring
In the real world I'd probably suggest you use this for maximum convenience and simplicity, but you lose a bit of efficiency in some cases.
Thus, the third option I'll present is std.utf.encode.
import std.utf;
char[4] buffer;
auto len = encode(buffer, a); // put the char in the buffer
writeln(buffer[0 .. len]); // slice the buffer. idup it if you want string specifically
This works for any input: char, wchar, or dchar, and will encode multi-byte code points into the string as well. To get a wstring, use wchar[2] for the buffer isntead. This is a good balance of correctness and efficiency, just at the trade of being a little less convenient.

how to convert or cast CString to LPWSTR?

I tried to use this code:
USES_CONVERSION;
LPWSTR temp = A2W(selectedFileName);
but when I check the temp variable, just get the first character
thanks in advance
If I recall correctly, CString is typedef'd to either CStringA or CStringW, depending on whether you're building Unicode or not.
LPWSTR is a "Long Pointer to a Wide STRing" -- aka: wchar_t*
If you want to pass a CString to a function that takes LPWSTR, you can do:
some_function(LPWSTR str);
// if building in unicode:
some_function(selectedFileName);
// if building in ansi:
some_function(CA2W(selectedFileName));
// The better way, especially if you're building in both string types:
some_function(CT2W(selectedFileName));
HOWEVER LPWSTR is non-const access to a string. Are you using a function that tries to modify the string? If so, you want to use an actual buffer, not a CString.
Also, when you "check" temp -- what do you mean? did you try cout << temp? Because that won't work (it will display just the first character):
char uses one byte per character. wchar_t uses two bytes per character. For plain english, when you convert it to wide strings, it uses the same bytes as the original string, but each character gets padded with a zero. Since the NULL terminator is also a zero, if you use a poor debugger or cout (which is uses ANSI text), you will only see the first character.
If you want to print a wide string to standard out, use wcout.
In short: You cannot. If you need a non-const pointer to the underlying character buffer of a CString object you need to call GetBuffer.
If you need a const pointer you can simply use static_cast<LPCWSTR>(selectedFilename).
I know this is a decently old question, but I had this same question and none of the previous answers worked for me.
This, however, did work for my unicode build:
LPWSTR temp = (LPWSTR)(LPCWSTR)selectedFileName;
LPWSTR is a "Long Pointer to a Wide String". It is like wchar*.
CString strTmp = "temp";
wchar* szTmp;
szTmp = new WCHAR[wcslen(strTmp) + 1];
wcscpy_s(szTmp, wcslen(strTmp) + 1, strTmp);

Convert std::wstring to WCHAR*

I have no idea how to convert a std::wstring to a WCHAR*
std::wstring wstrProcToSearch;
WCHAR * wpProcToSearch = NULL;
std::wcin >> wstrProcToSearch; // input std::wstring
// now i need to convert the wstring to a WCHAR*
Does anyone know how to accomplish this?
If you want to convert from std::wstring to const WCHAR* (i.e. the returned pointer gives read-only access to the string content), then calling std::wstring::c_str() method is just fine:
std::wstring wstrProcToSearch;
std::wcin >> wstrProcToSearch; // input std::wstring
// Convert to const WCHAR* (read-only access)
const WCHAR * wpszProcToSearch = wstrProcToSearch.c_str();
Instead, if you want to modify std::wstring's content, things are different. You can use &wstr[0] (where wstr is a non-empty instance of std::wstring) to access the content of the std::wstring (starting from the address of its first characters, and noting that characters are stored contiguously in memory), but you must pay attention to not overrun string's pre-allocated memory.
In general, if you have a std::wstring of length L, you can access characters from index 0
to (L-1).
Before C++17, overwriting the terminating '\0' (located at index L) was undefined behavior (in practice, it's been OK on Visual C++, at least with VC9/VS2008 and VC10/VS2010).
Starting with C++17, overwriting the terminating NUL ('\0') with another NUL has been made valid and is no more undefined behavior.
If the string has not the proper size (i.e. it's not big enough for your needs), then you can call std::wstring::resize() to make room for new characters (i.e. resizing internal std::wstring's buffer), and then use &wstr[0] to read-write std::wstring's content.
If the string is already the proper length and will not need to be changed, you can get a non-const pointer by taking a pointer to the first character:
WCHAR * wpProcToSearch = &wstrProcToSearch[0];
This is guaranteed to work in C++11 and there are no known implementations of C++03 where it doesn't.
If you only need a const pointer you should use c_str:
const WCHAR * wpProcToSearch = wstrProcToSearch.c_str();
I think you can use
wpProcToSearch = wstrProcToSearch.c_str()
like you do with a normal std::string.
I recommend this approach:
wstring str = L"Hallo x y 111 2222 3333 rrr 4444 ";
wchar_t* psStr = &str[0];
It is quite simple but you can not change the length of the string at all. So moving "\0" might not be valid...

Initialize wide char array

I have a wide char variable which I want to initialize with a size of string.
I tried following but didn't worked.
std::string s = "aaaaaaaaaaaaaaaaaaaaa"; //this could be any length
const int Strl = s.length();
wchar_t wStr[Strl ]; // This throws error message as constant expression expected.
what option do i have to achieve this? will malloc work in this case?
Since this is C++, use new instead of malloc.
It doesn't work because C++ doesn't support VLA's. (variable-length arrays)
The size of the array must be a compile-time constant.
wchar_t* wStr = new wchar_t[Strl];
//free the memory
delete[] wStr;
First of all, you can't just copy a string to a wide character array - everything is going to go berserk on you.
A std::string is built with char, a std::wstring is built with wchar_t. Copying a string to a wchar_t[] is not going to work - you'll get gibberish back. Read up on UTF8 and UTF16 for more info.
That said, as Luchian says, VLAs can't be done in C++ and his heap allocation will do the trick.
However, I must ask why are you doing this? If you're using std::string you shouldn't (almost) ever need to use a character array. I assume you're trying to pass the string to a function that takes a character array/pointer as a parameter - do you know about the .c_str() function of a string that will return a pointer to the contents?
std::wstring ws;
ws.resize(s.length());
this will give you a wchar_t container that will serve the purpose , and be conceptually a variable length container. And try to stay away from C style arrays in C++ as much as possible, the standard containers fit the bill in every circumstance, including interfacing with C api libraries. If you need to convert your string from char to wchar_t , c++11 introduced some string conversion functions to convert from wchar_t to char, but Im not sure if they work the other way around.

clone a wchar_t* in c++

I want to clone a path that is held in a var named szPath to a new wchar_t.
szPath is of the type wchar_t *. so i tried doing something like:
szPathNew = *szPath;
but this is referring to the same place in memory.
what should i do? i want to deep clone it.
Do this,
wchar_t clone[260];
wcscpy(clone,szPath);
Or, if you want to allocate memory yourself,
wchar_t *clone = new wchar_t[wcslen(szPath)+1];
wcscpy(clone,szPath);
//use it
delete []clone;
Check out : strcpy, wcscpy, _mbscpy at MSDN
However, if your implementation doesn't necessarily require raw pointers/array, then you should prefer this,
#include<string>
//MOST SAFE!
std:wstring clone(szPath);
Do not use raw C strings in C++. If you want wide character strings, you can use std::wstring:
#include <string>
...
std::wstring szPathClone1 = szPath; // Works as expected
If you insist on using wchar_t buffers directly, you can use the wcscpy function.
PS: You also seem to be confused by pointer usage, you should first learn more about pointers.
The _wcsdup function duplicates (clones) a string. Note that this allocates new memory, so you will need to free it later:
wchar_t * szPathClone = _wcsdup(szPath);
// ...
free(szPathClone);