Hi i'm using VS2010 and MBCS. Can anyone tell me how to convert an unsigned char to LPCSTR? Sorry i'm only new to c++...:) Thanks
This is the code it is failing on:
hr = MsiSetProperty(hInstall, "LOCKCODE", szLockCode);
ExitOnFailure(hr, "failed to set LOCKCODE");
szLockCode is the variable that needs to be converted.
An unsigned char array (unsigned char szLockCode[10] for instance) is technically already an LPCSTR. If you're using an array already then conversion is not the issue, if not, then you need an array. If you want a single character string, then you need an array of length 2. The character goes in the first position (szLockCode[0]) and the value 0 goes in the second position (szLockCode[1]).
You probably get error message like:
cannot convert parameter 3 from 'const char *' to 'LPCWSTR'
To avoid it you should either do type convertion:
hr = MsiSetProperty(hInstall, "LOCKCODE", (LPCSTR)szLockCode);
or use L prefix before string:
LPCSTR szLockCode = L"Some error";
hr = MsiSetProperty(hInstall, "LOCKCODE", szLockCode );
Here is a good explanation of what LPCSTR stand for:
LPCSTR, LPCTSTR and LPTSTR
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 trying to get a human readable string from SetupDiGetDeviceRegistryPropertyA() function.
My code is:
size_t strSize = RequiredSize / sizeof(wchar_t) + 1;
wchar_t* DevName = new wchar_t[strSize];
Name = new CHAR[strSize];
Result = SetupDiGetDeviceRegistryPropertyA(InfoSet, &InfoData, SPDRP_DEVICEDESC, &Type, reinterpret_cast<PBYTE>(DevName), RequiredSize, &RequiredSize);
If Result is true, I want to convert the DevName value to a string using the following code:
size_t sizeCon;
wcstombs_s(&sizeCon, Name, strSize, DevName, strSize);
But in "Name" I always get null and sizeCon is always '0'.
If I use a wide string (for example: wchar_t b[] = L"984567";) instead of the parameter DevName, I get a correct translation of the wide string to a character string.
In the Documenation of SetupDiGetDeviceRegistryPropertyA the PropertyBuffer parameter is described as a PBYTE.
In all code examples, which I saw, the code examples uses a wchar variable. This wchar variable which will be casted to a PBYTE, like I do.
Now I am confused.
Why in the code examples is a wchar variable used, when the type of PropertyBuffer is PBYTE?
What is the correct type to use in SetupDiGetDeviceRegistryPropertyA to get a string?
If I need to use a wchar variable, why the wcstombs_s function cannot convert the wchar variable to a char string?
Can someone help me to get the correct string from SetupDiGetDeviceRegistryPropertyA?
Thank you.
I've been looking around the internet for some solutions however they all convert it from a constant string. Here's a piece of code I took to convert strings to wchar_t without additional libraries. What I'm trying to do is, I want to change the background of my windows computer with my background. Now I can't assume that the folder that I downloaded is in C:\Downloads because some people change their downloads folder or maybe they moved the whole folder to another location. So in the first code, I'm trying to get the path of the .exe file.
string GetExePath() {
char buffer[MAX_PATH];
GetModuleFileNameA(NULL, buffer, MAX_PATH);
string::size_type pos = string(buffer).find_last_of("\\/");
return string(buffer).substr(0, pos + 1);//gets the first character in path up to the final backslash
}
Next I'm going to grab the picture that I want to make as my background in the same folder as the .exe file.
//error on the third parameter
int return_value = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, L(string)(GetExePath() + "\\picture.png"), SPIF_UPDATEINIFILE);
Error (active) E0040 expected an identifier
Error (active) E0020 identifier "L" is undefined
Error (active) E0254 type name is not allowed
Error (active) E0018 expected a ')'
After a while, I replaced the return type of the function and so it would return wchar_t*.
const wchar_t* GetExePath() {
char buffer[MAX_PATH];
GetModuleFileNameA(NULL, buffer, MAX_PATH);
string::size_type pos = string(buffer).find_last_of("\\/");
string path = string(buffer).substr(0, pos + 1);
path += "\\HandleCamWallpaperwithgradient.png";
cout << path << endl;
wstring wide;
for (int i = 0; i < path.length(); ++i){
wide += wchar_t(path[i]);
}
const wchar_t* result = wide.c_str();
return result;
}
However, the third parameter is showing an error saying
Error E0167 argument of type "const wchar_t *" is incompatible with parameter of type "PVOID"
So how can I fix it?
Edit: Someone thought that this was a duplicate and it isn't. How to convert string to wstring in C++ is NOT correlated with this question as the one who is asking on that thread is asking help for special characters.
Call the Unicode version GetModuleFileNameW() in the first place so you don't have to convert.
Also, never return a pointer to a string that is a local variable of a function (unless it is static)! Otherwise you will be returning a dangling pointer. Instead, return a std::wstring similar to your first version. You can use std::wstring directly as the buffer by using the "pointer-to-first-character" trick.
std::wstring GetExePath() {
std::wstring buffer(MAX_PATH, L'\0'); // reserve buffer
int len = GetModuleFileNameW(NULL, &buffer[0], buffer.size() );
buffer.resize(len); // resize to actual length
string::size_type pos = buffer.find_last_of(L"\\/");
return buffer.substr(0, pos + 1);//gets the first character in path up to the final backslash
}
The second error can be fixed like this:
std::wstring path = GetExePath() + L"picture.png";
int return_value = SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, &path[0], SPIF_UPDATEINIFILE);
The pvParam parameter of SystemParametersInfoW is a pointer to non-const data, so we have to use the "pointer-to-first-character" trick here again (to avoid ugly const_cast).
With C++17, this could be written as a one-liner:
int return_value = SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (GetExePath() + L"picture.png").data(), SPIF_UPDATEINIFILE);
Other things to improve, left as an exercise:
Check for the error condition ERROR_INSUFFICIENT_BUFFER as described in the comments of GetModuleFileName() MSDN reference so you can support pathes longer than MAX_PATH.
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();
I'm trying to compile some code, but I'm getting an error:
Error invalid conversion from DWORD to const char *
Here's the code I'm trying to compile:
hWindow = FindWindow(NULL, "Window");
if (hWindow){
GetWindowThreadProcessId(hWindow, &pid);
}
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
if(hProcess != NULL) {
SetWindowText(GetDlgItem(MyWindow, MyStatic), pid);
}
How do I convert a DWORD to a const char *?
SetWindowText expects a const char * (i.e. a C-string) and you are passing it a number (pid), it's obvious that you get an error.
The standard C++ way to perform the conversion is to use a string stream (from header <sstream>:
std::ostringstream os;
os<<pid;
SetDlgItemText(MyWindow, MyStatic, os.str().c_str());
(here I used SetDlgItemText instead of GetDlgItem+SetWindowText to save typing, but it's the same thing)
Alternatively, you can use snprintf.
char buffer[40];
snprintf(buffer, sizeof(buffer), "%u", pid);
SetDlgItemText(MyWindow, MyStatic, buffer);
In this line
SetWindowText(GetDlgItem(MyWindow, MyStatic), pid);
pid is a DWORD (as you used it in GetWindowThreadProcessId(hWindow, &pid) which takes a LPDWORD as the second argument). However, SetWindowText expects a C-string as it's second argument, so instead of pid, you must pass a value of type char * or char [].
To display the value of pid, you can make use of sprintf:
char * str = new char[10];
sprintf(str,"%d",pid);
You may have to modify the size of str a little (10 might be too small, or bigger than necessary - that's up to you and your situation).