C++: convert LPTSTR to char array [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Convert lptstr to char*
I need to convert an LPTSTR p to CHAR ch[]. I am new to C++.
#include "stdafx.h"
#define _WIN32_IE 0x500
#include <shlobj.h>
#include <atlstr.h>
#include <iostream>
#include <Strsafe.h>
using namespace std;
int main(){
int a;
string res;
CString path;
char ch[MAX_PATH];
LPTSTR p = path.GetBuffer(MAX_PATH);
HRESULT hr = SHGetFolderPath(NULL,CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, p);
/* some operation with P and CH */
if(SUCCEEDED(hr))
{ /* succeeded */
cout << ch;
} /* succeeded */
else
{ /* failed */
cout << "error";
} /* failed */
cin >> a;
return 0;
}
Thanks in advance.

LPTSTR is a (non-const) TCHAR string. Depends if it is Unicode or not it appears. LPTSTR is char* if not Unicode, or w_char* if so.
If you are using non-Unicode strings LPTSTR is just a char*, otherwise do:
size_t size = wcstombs(NULL, p, 0);
char* CharStr = new char[size + 1];
wcstombs( CharStr, p, size + 1 );
Also, this link can help:
Convert lptstr to char*

LPTSTR means TCHAR* (expanding those Win32 acronyms typedefs can make it easier to understand them). TCHAR expands to char in ANSI/MBCS builds, and to wchar_t in Unicode builds (which should be the default in these days for better internationalization support).
This table summarizes the TCHAR expansions in ANSI/MBCS and Unicode builds:
| ANSI/MBCS | Unicode
--------+----------------+-----------------
TCHAR | char | wchar_t
LPTSTR | char* | wchar_t*
LPCTSTR | const char* | const wchar_t*
So, in ANSI/MBCS builds, LPTSTR expands to char*; in Unicode builds it expands to wchar_t*.
char ch[MAX_PATH] is an array of char's in both ANSI and Unicode builds.
If you want to convert from a TCHAR string (LPTSTR) to an ANSI/MBCS string (char-based), you can use ATL string conversion helpers, e.g.:
LPTSTR psz; // TCHAR* pointing to something valid
CT2A ch(psz); // convert from TCHAR string to char string
(Note also that in your original code you should call CString::ReleaseBuffer() which is the symmetric of CString::GetBuffer().)
Sample code follows:
// Include ATL headers to use string conversion helpers
#include <atlbase.h>
#include <atlconv.h>
...
LPTSTR psz = path.GetBuffer(MAX_PATH);
HRESULT hr = SHGetFolderPath(NULL,CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, psz);
path.ReleaseBuffer();
if (FAILED(hr))
{
// handle error
...
}
// Convert from TCHAR string (CString path) to char string.
CT2A ch(path);
// Use ch...
cout << static_cast<const char*>(ch) << endl;
Note also that the conversion from Unicode to ANSI can be lossy.

First, you defined char* ch[MAX_PATH] instead of char ch[MAX_PATH].
Regarding your question, LPTSTR (Long Pointer to TCHAR String) is equivalent to LPWSTR (which is w_char*) if it's unicode, or just LPSTR (char*) if it is not. You can use this link for reference about conversion in each case.
EDIT: To cut to the chase, here's some code:
if (sizeof(TCHAR) == sizeof(char)) // String is non-unicode
strcpy(ch, (char*)(p));
else // String is unicode
wcstombs(ch, p, MAX_PATH);
EDIT 2: In windows I would recommend using TCHAR instead of char. It will save you some headache.
EDIT 3: As a side note, if you want to prevent Visual Studio from flooding you with warnings about unsafe functions, you can add something like the following to the very beginning of your code:
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

Related

My winreg function is not being recognized

The error:
error: no matching function for call to 'RegCreateKeyExW'
What I am including:
#include <iostream>
#include <Windows.h>
#include <stdio.h>
#include <string>
#include <winreg.h>
My code:
HKEY hKey;
LONG result = 0;
char *path = "SYSTEM\\CurrentControlSet\\Control\\IDConfigDB\\Hardware Profiles\\0001";
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, path, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS) {
printf("2. success \n");
} else {
printf("fail\n");
}
I have tried everything but this error won't vanish, I would aprecciate if someone could help me!
You are calling the TCHAR version of RegCreateKeyEx(). It is clear from the error message that RegCreateKeyEx() is resolving to the Unicode version, RegCreateKeyExW() (because UNICODE is defined in your build config). That version takes in a wide wchar_t string as input, but you are passing in a narrow char string instead.
You can either:
use a TCHAR string, to match the TCHAR function your code is calling:
const TCHAR* path = TEXT("SYSTEM\\CurrentControlSet\\Control\\IDConfigDB\\Hardware Profiles\\0001");
use a Unicode string, to match the Unicode function actually being called at runtime:
const wchar_t *path = L"SYSTEM\\CurrentControlSet\\Control\\IDConfigDB\\Hardware Profiles\\0001";
use the ANSI version of the function, RegCreateKeyExA(), to match your original string:
if (RegCreateKeyExA(...) == ERROR_SUCCESS) {

Conversion from TCHAR to std::string, other way than using WideCharToMultiByte?

I have to convert a TCHAR variable (which is a path retrieved with OpenBrowseDir) into a std::string.
I'm currently having this code which works. I'm using WideCharToMultiByte.
TCHAR path[MAX_PATH];
OpenBrowseDir(path);
/*conversion from TCHAR to std::string*/
char ch[MAX_PATH];
char DefChar = ' ';
WideCharToMultiByte(CP_ACP, 0, path, -1, ch, MAX_PATH, &DefChar, NULL);
string spath(ch);
On my project TCHAR is wchar_t.
In OpenBrowseDir I'm opening a browse dialog so the user can select a directory. I'm using a variable BROWSEINFO bi, and bi.pszDisplayName is of type TCHAR.
Are there other better solutions?

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

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

How to convert from wchar_t to LPSTR?

How can I convert a string from wchar_t to LPSTR.
A wchar_t string is made of 16-bit units, a LPSTR is a pointer to a string of octets, defined like this:
typedef char* PSTR, *LPSTR;
What's important is that the LPSTR may be null-terminated.
When translating from wchar_t to LPSTR, you have to decide on an encoding to use. Once you did that, you can use the WideCharToMultiByte function to perform the conversion.
For instance, here's how to translate a wide-character string into UTF8, using STL strings to simplify memory management:
#include <windows.h>
#include <string>
#include <vector>
static string utf16ToUTF8( const wstring &s )
{
const int size = ::WideCharToMultiByte( CP_UTF8, 0, s.c_str(), -1, NULL, 0, 0, NULL );
vector<char> buf( size );
::WideCharToMultiByte( CP_UTF8, 0, s.c_str(), -1, &buf[0], size, 0, NULL );
return string( &buf[0] );
}
You could use this function to translate a wchar_t* to LPSTR like this:
const wchar_t *str = L"Hello, World!";
std::string utf8String = utf16ToUTF8( str );
LPSTR lpStr = utf8String.c_str();
I use this
wstring mywstr( somewstring );
string mycstr( mywstr.begin(), mywstr.end() );
then use it as mycstr.c_str()
(edit, since i cannot comment) this is how i used this, and it works fine:
#include <string>
std::wstring mywstr(ffd.cFileName);
std::string mycstr(mywstr.begin(), mywstr.end());
pRequest->Write(mycstr.c_str());

How can I copy a CHAR Variable to WCHAR Variable in C++

I want to convert a CHAR file to UNICODE file.
I read a file character by character in CHAR file type and then save this character in a CHAR Variable and then I want to copy this CHAR Variable to a WCHAR Variable and then I Write the the WCHAR Variable in to a UNICODE file.
here is the code :
#include<Windows.h>
#include<tchar.h>
int _tmain(int argc, LPCTSTR argv[])
{
HANDLE hInfile, hOutfile;
CHAR f1;
WCHAR f2;
DWORD Rd, Wrt;
INT i;
CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL,NULL);
CreateFile(argv[2], GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);
while ((ReadFile(hInfile, &f1, sizeof(CHAR), &Rd, NULL) && Rd>0))
{
**_tccpy(f2, f1);**
WriteFile(hOutfile, &f2, Rd, &Wrt, NULL);
}
CloseHandle(hInfile);
CloseHandle(hOutfile);
}
in bold code is the problem, how can I copy CHAR Variable to a WCHAR Variable.
the _tccpy function and strcpy function cant do this, because the prototype of both of them is char or wachar.
Microsoft Specific
Use wmain instead of main if you want to write portable code that adheres to the Unicode programming model.
wmain( int argc, wchar_t *argv[ ], wchar_t *envp[ ] )
wmain at ms http://msdn.microsoft.com/en-us/library/bky3b5dh(VS.80).aspx
I have always found these string basics and conversions very useful when dealing with Unicode in C++.