This question already has answers here:
conversion of Cstring to BYTE
(5 answers)
Closed 4 years ago.
I am trying to convert CString to byte [] array in Visual Studio MFC. Please see the code below.
CString str_text;
GetDlgItemText(IDC_KEY_TEXT, str_text);
BYTE A[] = "hi I love stackoverflow";
BYTE A[] = str_text;
Here, BYTE A [] is a byte array.
Regardless of CString and GetDlgItemText function, if I do only (1) my program does well.
But If you type CString(str_text)(2) instead of "hi I love stackoverflow" I have a error. That's error is "it couldn't convert CString to byte array".
I would like to convert CString to byte array. Please tell me where my mistake is.
Here is the proper way of doing this. I assume you deal with Unicode strings:
CStringW str = L"Hello World";
// convert to UTF-8
CStringA utf8 = CW2A(str, CP_UTF8);
CByteArray Bytes;
const size_t nBytes = sizeof(CStringA::XCHAR) * utf8.GetLength();
Bytes.SetSize( nBytes );
std::memcpy( Bytes.GetData(), static_cast<BYTE const*>utf8, nBytes );
Related
After getting a struct from C# to C++ using C++/CLI:
public value struct SampleObject
{
LPWSTR a;
};
I want to print its instance:
printf(sampleObject->a);
but I got this error:
Error 1 error C2664: 'printf' : cannot convert parameter 1 from
'LPWSTR' to 'const char *'
How can I convert from LPWSTR to char*?
Thanks in advance.
Use the wcstombs() function, which is located in <stdlib.h>. Here's how to use it:
LPWSTR wideStr = L"Some message";
char buffer[500];
// First arg is the pointer to destination char, second arg is
// the pointer to source wchar_t, last arg is the size of char buffer
wcstombs(buffer, wideStr, 500);
printf("%s", buffer);
Hope this helped someone! This function saved me from a lot of frustration.
Just use printf("%ls", sampleObject->a). The use of l in %ls means that you can pass a wchar_t[] such as L"Wide String".
(No, I don't know why the L and w prefixes are mixed all the time)
int length = WideCharToMultiByte(cp, 0, sampleObject->a, -1, 0, 0, NULL, NULL);
char* output = new char[length];
WideCharToMultiByte(cp, 0, sampleObject->a, -1, output , length, NULL, NULL);
printf(output);
delete[] output;
use WideCharToMultiByte() method to convert multi-byte character.
Here is example of converting from LPWSTR to char*
or wide character to character.
/*LPWSTR to char* example.c */
#include <stdio.h>
#include <windows.h>
void LPWSTR_2_CHAR(LPWSTR,LPSTR,size_t);
int main(void)
{
wchar_t w_char_str[] = {L"This is wide character string test!"};
size_t w_len = wcslen(w_char_str);
char char_str[w_len + 1];
memset(char_str,'\0',w_len * sizeof(char));
LPWSTR_2_CHAR(w_char_str,char_str,w_len);
puts(char_str);
return 0;
}
void LPWSTR_2_CHAR(LPWSTR in_char,LPSTR out_char,size_t str_len)
{
WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,in_char,-1,out_char,str_len,NULL,NULL);
}
Here is a Simple Solution. Check wsprintf
LPWSTR wideStr = "some text";
char* resultStr = new char [wcslen(wideStr) + 1];
wsprintfA ( resultStr, "%S", wideStr);
The "%S" will implicitly convert UNICODE to ANSI.
Don't convert.
Use wprintf instead of printf:
wprintf
See the examples which explains how to use it.
Alternatively, you can use std::wcout as:
wchar_t *wstr1= L"string";
LPWSTR wstr2= L"string"; //same as above
std::wcout << wstr1 << L", " << wstr2;
Similarly, use functions which are designed for wide-char, and forget the idea of converting wchar_t to char, as it may loss data.
Have a look at the functions which deal with wide-char here:
Unicode in Visual C++
I'm experimenting with the new C++ 2020 std::format function. I would like to represent the output with a width deduced from its type. Currently I have this line:
std::wstring wstr = std::format( L"{0:#0{1}x}", ::GetLastError(), sizeof( ::GetLastError() ) * 2 );
This results in the value L"0x000002".
Is # supposed to count the 0x as part of the width? (If I remove it, I get 8 nibbles as expected)
Is there a better way of formulating this format string, without sizeof thing?
Is # supposed to count the 0x as part of the width? (If I remove it, I get 8 nibbles as expected)
Yes. There is an example in [format.string.std]/13 which illustrates this. The whole string is 6 characters, including the 0x:
string s2 = format("{:#06x}", 0xa); // value of s2 is "0x000a"
This is similar to what printf does.
Is there a better way of formulating this format string, without sizeof thing?
If this is something you want to do often, then you can create your own type and define its formatting internally so that you just write:
std::wstring wstr = std::format( L"{}", PrettyHex{::GetLastError()});
But that's just moving where the sizeof happens - you still need to manually provide it somewhere, there's no shortcut here.
Anyway, I wrote this specialization. So if someone is interested, here it is:
#include <format>
#include <iostream>
typedef unsigned long DWORD;
struct PrettyHex {
DWORD dwValue;
};
template<>
struct std::formatter< PrettyHex, wchar_t > : std::formatter< std::wstring, wchar_t > {
auto format( PrettyHex prettyHex, std::wformat_context& context ) {
std::wstring wstrPrettyHex = std::format( L"0x{:0{}x}", prettyHex.dwValue, sizeof prettyHex.dwValue * 2 );
return std::formatter< std::wstring, wchar_t >::format( wstrPrettyHex, context );
}
};
int wmain() {
DWORD dwTest = 102;
std::wstring wstrTest = std::format( L"dwTest formatted as DWORD: {}\ndwTest formatted as PrettyHex: {}\n", dwTest, PrettyHex{ dwTest } );
std::wcout << wstrTest;
return 0;
}
My goal is to get this:
BYTE Data1[] = {0x6b,0x65,0x79};
BYTE Data2[] = {0x6D,0x65,0x73,0x73,0x61,0x67,0x65};
But my starting point is:
std::string msg = "message";
std::string key = "key";
I am not able to get from std::string to BYTE[].
I tried the following:
std::vector<BYTE> msgbytebuffer(msg.begin(), msg.end());
BYTE* Data1 = &msgbytebuffer[0];
This didn't cause compile or run time error. However, the end result (I feed this to a winapi function - crypto api) was not the same as when I used the actual byte array like in top most ({0x6D,0x65,0x73,0x73,0x61,0x67,0x65}).
You can use string::c_str() function which returns a pointer to c style string that can be passed to winapi functions like:
foo(string.c_str());
What it actually does is that it returns a pointer to an array that contains a null-terminated sequence of characters.
I suppose BYTE[] is actually a char array. You can assign your std::string to char array by doing:
std::string str = "hello";
BYTE byte[6]; // null terminated string;
strcpy(byte, str.c_str()); // copy from str to byte[]
If you want to copy the str without the 0 at the end, use strncpy instead:
BYTE byte[5];
strncpy(byte, str.c_str(), str.length());
Seems me that winapi is waiting a null terminated c-string. You can achieve that by using:
msg.c_str();
or, using your BYTE type, something like that:
std::vector<BYTE> msgbytebuffer(msg.length() + 1, 0);
std::copy(msg.begin(), msg.end(), msgbytebuffer.begin());
This question already has answers here:
Guaranteed lifetime of temporary in C++?
(6 answers)
Closed 8 years ago.
I am currently doing DirectX11 and trying to convert a UTF8 string into a LPCWSTR. I've written a utility function to aid me in the conversion:
// Convert an UTF8 string to a wide Unicode String
std::wstring WidenString(const std::string &string)
{
int size_needed = MultiByteToWideChar(CP_UTF8, 0, string.c_str(), string.size(), NULL, 0);
std::wstring wstring(size_needed, 0);
MultiByteToWideChar(CP_UTF8, 0, string.c_str(), string.size(), &wstring[0], size_needed);
return wstring;
}
I've used the debugger to verify if it works. This is working:
Debugger says wndClassEx.lpszClassName = L"Hello"
std::wstring str = WidenString("Hello");
wndClassEx.lpszClassName = str.c_str();
This is not working:
Debugger says wndClassEx.lpszClassName = L"ﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮ..."
wndClassEx.lpszClassName = WidenString("Hello").c_str();
Can someone explain to me what is wrong with my code?
WidenString() returns a wstring by value. In the first snippet, wndClassEx.lpszClassName will point to a valid memory location as long as the variable str remains in scope i.e. it does not get destroyed.
In the second case the return value does go out of scope at the end of the expression (at the ;) and wndClassEx.lpszClassName then points to invalid memory.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Char array gives error when initializing
I want to insert an environment variable in the windows registry, so i tied the following C++ code :
string appDataPath = getenv("appdata");
HKEY hkey;
char value[] = appDataPath.c_str();
RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\Currentversion\\Run", 0, KEY_SET_VALUE, &hkey);
RegSetValueEx (hkey, "MyProgram", 0, REG_SZ, (LPBYTE) value, strlen(value) + 1);
RegCloseKey(hkey);
The codeblock debug output tell me : error: initializer fails to determine size of 'value'
I think it's because the compilator need to know the size of my variable before compiling, however i don't know how to fix that...
Thanks !
c_str() returns a const char*, not a char[]. Change
char value[] = appDataPath.c_str();
to
const char* value = appDataPath.c_str();
The compiler is giving the error because an array variable requires a length - which is not being provided.
Use
const char * value = appDataPath.c_str();
(Read the < string > reference to find the return type of c_str(), it will tell you that it is indeed const char *.)
Regarding your question of how to concatenate two strings:
Do that with C++ strings rather than with char *s and convert them later:
string newstring = appDataPath;
newstring.append("some text");
const char * value = newstring.c_str();