Below is my code :
string szDllPath = "12345";
size_t size = szDllPath.length();
TCHAR* wArr = new TCHAR[size];
for (size_t i = 0; i < size; ++i)
wArr[i] = _T(szDllPath[i]);
cout<<szDllPath<<endl;
cout<<wArr<<endl;
And I get this :
I don't understand why I get the extra characters, and how to solve it ?
You forgot to provide space for and add a terminating zero.
Preface:
New code should not be using Generic-Text Mappings. They were invented in the 90's to ease porting code from ANSI systems (Win9x) to Unicode systems (Windows NT). TCHAR expands to either char or wchar_t controlled by the UNICODE and _UNICODE preprocessor symbols.
Don't use TCHAR, unless you have to support Win9x.
Analysis:
You are making this way more complicated, than it is. Since this code
TCHAR* wArr = ...;
cout << wArr << endl;
writes a character string to cout (vs. a pointer value), you haven't defined the preprocessor symbols UNICODE or _UNICODE. In other words: You are using MBCS character encoding (see Unicode and MBCS), and the following would produce identical output:
string szDllPath = "12345";
cout << szDllPath.c_str() << endl;
If that is really what you want (and I doubt it is), then simply calling std::basic_string::cstr() is sufficient (use std::basic_string::data(), if you need a mutable string).
Recommended solution:
Use Unicode throughout. The following solves your immediate problem, if you are using a character string literal.
wstring szDllPath = L"12345";
wcout << szDllPath.c_str() << endl;
If you aren't using a character string literal and do need to convert from a std::string to a wide character string, you can use MFC's CString class to perform the conversion:
CStringW wideString(szDllPath.c_str()); // Conversion c'tor, taking a const char*
const wchar_t* = (LPCWSTR)wideString; // Invoke operator LPCWSTR()
You need to be careful when working with char* variants of strings in C and C++. They're required to have a terminating 0 at the and, and you didn't provide the space for it
TCHAR* wArr = new TCHAR[size+1];
...
/*add a terminating zero after the loop*/
wArr[size] = 0;
It would work as expected.
Also, avoid such bare char* operations if you can.
Related
How to print array of LPCTSTR
example
LPCTSTR pszValueNames[] = { L"partnerID", L"partnerSubID", L"transactionID" };
for (int i = 0; i < (sizeof(pszValueNames) / sizeof(LPCWSTR)); i++)
{
cout << (*pszValueNames[i]) << endl;
}
Above give some numbers which is not real lpctstr values.
When i use wchar_t* and all other basic types it spit good values.
The reason why you get the address printed is that std::cout works with std::string, which is char based. An LPCWSTR is a wide string pointer type, and cout has no idea how to display wide strings "as strings".
You should use std::wcout to handle a wide string.
std::wcout << pszValueNames[i] << std::endl;
Also, your usage of LPCTSTR is not correct, even though your program may work. If you know you're using wide strings, specify LPCWSTR anywhere you would have used LPCTSTR. The reason is that LPCTSTR is not necessarily a wide string pointer type, depending on the type of build (MBCS or Unicode) that you are using.
So in a nutshell, your string pointer declarations are a hodge-podge of different string types, where some functions may work (if the LPCTSTR is a non-wide char pointer), while other string handling functions won't work.
Basically, if you're going to use LPCTSTR or LPTSTR, then all of your code that handles string or string pointer types should use "build-neutral" types, i.e. use LPCTSTR, TCHAR, LPTSTR, _T(), etc. These types will change seemlessly if you go from an MBCS build to a Unicode build (and vice-versa for whatever reason).
If on the other hand, if you know that the build will only ever be Unicode, then LPCWSTR and LPWSTR should be used throughout your program. Conversely, if you know and can guarantee that the build will only be MBCS, then use LPCSTR and LPSTR in your program.
The best thing to do is either use the build-neutral types (LPCTSTR, etc.) throughout your application, or change all of these to wide string types (LPCWSTR, etc.). The MBCS builds are becoming very rare these days, so might as well start developing using wide string types, and only use char string types in your application when you're interfacing to other functions that rely on char based strings.
Two issues. First, you're iterating over the wrong size:
for (int i = 0; i < (sizeof(pszValueNames) / sizeof(LPCWSTR)); i++)
// ^^^^^^^
That should be LPCTSTR. Or, to avoid this kind of error, just *pszValueNames. Or likely the reverse, LPCWSTR is the corret type but you declared the array to be LPCTSTR instead.
Secondly:
cout << (*pszValueNames[i]) << endl;
That would dereference the ith string - which would print only the first character. To print the whole string you don't need the dereference. Also, you would need to use wcout as cout does not work with wchar_t:
wcout << pszValueNames[i] << endl;
std::wcout was already mentioned, but I'd like to add that this is a nice example of how C++11 features can improve legacy or C-based code – if you can use a C++11 compiler, that is.
In C++11, you can write your loop like this:
for (auto const &name : pszValueNames)
{
std::wcout << name << std::endl;
}
No more sizeof or dereferencing issues to worry about. And if you later change your array to something like std::array<std::wstring> or std::vector<std::wstring> or std::set<std::wstring>, then the loop will not have to be modified at all (the element type of the container will just have to remain compatible with std::wcout).
edit: made code example use const &
The [] operator accesses the index*sizeof(type) part of the memory after the pointed mem. value, and this operator takes a pointer. You dont need the * there... *pszValue is dereferencing, true, but that is done implicitly here.... so you are actually dereferencing a value...
Quote from MSDN: "Usually, the value represented by postfix-expression is a pointer value, such as an array identifier, and expression is an integral value (including enumerated types). However, all that is required syntactically is that one of the expressions be of pointer type and the other be of integral type."
See the [] operator here
Is there any method?
My computer is AMD64.
::std::string str;
BOOL loadU(const wchar_t* lpszPathName, int flag = 0);
When I used:
loadU(&str);
the VS2005 compiler says:
Error 7 error C2664:: cannot convert parameter 1 from 'std::string *__w64 ' to 'const wchar_t *'
How can I do it?
First convert it to std::wstring:
std::wstring widestr = std::wstring(str.begin(), str.end());
Then get the C string:
const wchar_t* widecstr = widestr.c_str();
This only works for ASCII strings, but it will not work if the underlying string is UTF-8 encoded. Using a conversion routine like MultiByteToWideChar() ensures that this scenario is handled properly.
If you have a std::wstring object, you can call c_str() on it to get a wchar_t*:
std::wstring name( L"Steve Nash" );
const wchar_t* szName = name.c_str();
Since you are operating on a narrow string, however, you would first need to widen it. There are various options here; one is to use Windows' built-in MultiByteToWideChar routine. That will give you an LPWSTR, which is equivalent to wchar_t*.
You can use the ATL text conversion macros to convert a narrow (char) string to a wide (wchar_t) one. For example, to convert a std::string:
#include <atlconv.h>
...
std::string str = "Hello, world!";
CA2W pszWide(str.c_str());
loadU(pszWide);
You can also specify a code page, so if your std::string contains UTF-8 chars you can use:
CA2W pszWide(str.c_str(), CP_UTF8);
Very useful but Windows only.
If you are on Linux/Unix have a look at mbstowcs() and wcstombs() defined in GNU C (from ISO C 90).
mbs stand for "Multi Bytes String" and is basically the usual zero terminated C string.
wcs stand for Wide Char String and is an array of wchar_t.
For more background details on wide chars have a look at glibc documentation here.
Need to pass a wchar_t string to a function and first be able to create the string from a literal string concantenated with an integer variable.
The original string looks like this, where 4 is the physical drive number, but I want that to be changeable to match whatever drive number I want to pass to the function
auto TargetDrive = L"\\\\.\\PhysicalDrive4";
The following works
int a = 4;
std::string stddrivestring = "\\\\.\\PhysicalDrive" + to_string(a);
std::wstring widedrivestring = std::wstring(stddrivestring.begin(), stddrivestring.end());
const wchar_t* TargetDrive = widedrivestring.c_str();
How can I convert a Unicode string to a char* or char* const in embarcadero c++ ?
String text = "Hello world";
char *txt = AnsiString(text).c_str();
Older text.t_str() is now AnsiString(String).c_str()
"Unicode string" really isn't specific enough to know what your source data is, but you probably mean 'UTF-16 string stored as wchar_t array' since that's what most people who don't know the correct terminology use.
"char*" also isn't enough to know what you want to target, although maybe "embarcadero" has some convention. I'll just assume you want UTF-8 data unless you mention otherwise.
Also I'll limit my example to what works in VS2010
// your "Unicode" string
wchar_t const * utf16_string = L"Hello, World!";
// #include <codecvt>
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,wchar_t> convert;
std::string utf8_string = convert.to_bytes(utf16_string);
This assumes that wchar_t strings are UTF-16, as is the case on Windows, but otherwise is portable code.
You can reinterpret any array as an array of char pointers legally. So if your Unicode data comes in 4-byte code units like
char32_t data[100];
then you can access it as a char array:
char const * p = reinterpret_cast<char const*>(data);
for (std::size_t i = 0; i != sizeof data; ++i)
{
std::printf("Byte %03zu is 0x%02X.\n", i, p[i]);
}
That way, you can examine the individual bytes of your Unicode data one by one.
(That has of course nothing to do with converting the encoding of your text. For that, use a library like iconv or ICU.)
If you work with Windows:
//#include <windows.h>
u16string utext = u"объява";
char text[0x100];
WideCharToMultiByte(CP_UTF8,NULL,(const wchar_t*)(utext.c_str()),-1,text,-1,NULL,NULL);
cout << text;
We can't use std::wstring_convert, wherefore is not available in MinGW 4.9.2.
I want to convert a CString into a char[]. Some body tell me how to do this?
My code is like this :
CString strCamIP1 = _T("");
char g_acCameraip[16][17];
strCamIP1 = theApp.GetProfileString(strSection, _T("IP1"), NULL);
g_acCameraip[0] = strCamIP1;
This seems to be along the right lines; http://msdn.microsoft.com/en-us/library/awkwbzyc.aspx
CString aCString = "A string";
char myString[256];
strcpy(myString, (LPCTSTR)aString);
which in your case would be along the lines of
strcpy(g_acCameraip[0], (LPCTSTR)strCamIP1);
From MSDN site:
// Convert to a char* string from CStringA string
// and display the result.
CStringA origa("Hello, World!");
const size_t newsizea = (origa.GetLength() + 1);
char *nstringa = new char[newsizea];
strcpy_s(nstringa, newsizea, origa);
cout << nstringa << " (char *)" << endl;
CString is based on TCHAR so if don't compile with _UNICODE it's CStringA or if you do compile with _UNICODE then it is CStringW.
In case of CStringW conversion looks little bit different (example also from MSDN):
// Convert to a char* string from a wide character
// CStringW string. To be safe, we allocate two bytes for each
// character in the original string, including the terminating
// null.
const size_t newsizew = (origw.GetLength() + 1)*2;
char *nstringw = new char[newsizew];
size_t convertedCharsw = 0;
wcstombs_s(&convertedCharsw, nstringw, newsizew, origw, _TRUNCATE );
cout << nstringw << " (char *)" << endl;
You could use wcstombs_s:
// Convert CString to Char By Quintin Immelman.
//
CString DummyString;
// Size Can be anything, just adjust the 100 to suit.
const size_t StringSize = 100;
// The number of characters in the string can be
// less than String Size. Null terminating character added at end.
size_t CharactersConverted = 0;
char DummyToChar[StringSize];
wcstombs_s(&CharactersConverted, DummyToChar,
DummyString.GetLength()+1, DummyString,
_TRUNCATE);
//Always Enter the length as 1 greater else
//the last character is Truncated
If you are using ATL you could use one of the conversion macros. CString stores data as tchar, so you would use CT2A() (C in macro name stands for const):
CString from("text");
char* pStr = CT2A((LPCTSTR)from);
Those macros are smart, if tchar represents ascii (no _UNICODE defined), they just pass the pointer over and do nothing.
More info below, under ATL String-Conversion Classes section:
http://www.369o.com/data/books/atl/index.html?page=0321159624%2Fch05.html
CStringA/W is cheaply and implicitly convertible to const char/wchar_t *. Whenever you need C-style string, just pass CString object itself (or the result of .GetString() which is the same). The pointer will stay valid as long as string object is alive and unmodified.
strcpy(g_acCameraip[0], strCamIP1);
// OR
strcpy(g_acCameraip[0], strCamIP1.GetString());
If you need writable (non-const) buffer, use .GetBuffer() with optional maximum length argument.
If you have CStringW but you need const char* and vice versa, you can use a temporary CStringA object:
strcpy(g_acCameraip[0], CStringA(strCamIP1).GetString());
But a much better way would be to have array of CStrings. You can use them whereever you need null-terminated string, but they will also manage string's memory for you.
std::vector<CString> g_acCameraip(16);
g_acCameraip[0] = theApp.GetProfileString(strSection, _T("IP1"), NULL);
Use memcpy .
char c [25];
Cstring cstr = "123";
memcpy(c,cstr,cstr.GetLength());
Do you really have to copy the CString objects into fixed char arrays?
enum { COUNT=16 };
CString Cameraip[COUNT];
Cameraip[0] = theApp.GetProfileString(strSection, _T("IP1"), NULL);
// add more entries...
...and then - later - when accessing the entries, for example like this
for (int i=0; i<COUNT; ++i) {
someOp(Cameraip[i]); // the someOp function takes const CString&
}
...you may convert them, if needed.
fopen is the function which needs char* param. so if you have CString as available string, you can just use bellow code.
be happy :)
Here, cFDlg.GetPathName().GetString(); basically returns CString in my code.
char*pp = (char*)cFDlg.GetPathName().GetString();
FILE *fp = ::fopen(pp,"w");
CString str;
//Do something
char* pGTA = (LPTSTR)(LPCTSTR)str;//Now the cast
Just (LPTSTR)(LPCTSTR). Hope this is what you need :)
char strPass[256];
strcpy_s( strPass, CStringA(strCommand).GetString() );
It's simple
ATL CStrings allow very simple usage without having to do a lot of conversions between types. You can most easily do:
CString cs = "Test";
const char* str = static_cast<LPCTSTR>(cs);
or in UNICODE environment:
CString cs = "Test";
const wchar_t* str = static_cast<LPCTSTR>(cs);
How it works
The static_cast (or alternatively C-Style cast) will trigger the CString::operator LPCTSTR, so you don't do any pointer reinterpretation yourself but rely on ATL code!
The documentation of this cast operator says:
This useful casting operator provides an efficient method to access the null-terminated C string contained in a CString object. No characters are copied; only a pointer is returned. Be careful with this operator. If you change a CString object after you have obtained the character pointer, you may cause a reallocation of memory that invalidates the pointer.
Modifiable Pointers
As mentioned in the above statement, the returned pointer by the cast operator is not meant to be modified. However, if you still need to use a modifiable pointer for some outdated C libraries, you can use a const_cast (if you are sure that function wont modify the pointer):
void Func(char* str) // or wchar_t* in Unicode environment
{
// your code here
}
// In your calling code:
CString cs = "Test";
Func(const_cast<LPTSTR>(static_cast<LPCTSTR>(test))); // Call your function with a modifiable pointer
If you wish to modify the pointer, you wont get around doing some kind of memory copying to modifiable memory, as mentioned by other answers.
There is a hardcoded method..
CString a = L"This is CString!";
char *dest = (char *)malloc(a.GetLength() + 1);
// +1 because of NULL char
dest[a.GetLength()] = 0; // setting null char
char *q = (char *)a.m_pszData;
//Here we cannot access the private member..
//The address of "m_pszData" private member is stored in first DWORD of &a...
//Therefore..
int address = *((int *)&a);
char *q = (char *)address;
// Now we can access the private data!, This is the real magic of C
// Size of CString's characters is 16bit...
// in cstring '1' will be stored as 0x31 0x00 (Hex)
// Here we just want even indexed chars..
for(int i = 0;i<(a.GetLength()*2);i += 2)
dest[i/2] = *(q+i);
// Now we can use it..
printf("%s", dest);
#define __T(x) L ## x
Found in code from one of the MFC source header file. It is mostly used for converting strings to ........ (I don't know what). If I am correct it converts strings to LPCTSTR...don't know what that type is either...
I can't seem to convert char* into LPCTSTR. While MFC file handling, the following code will always return error while trying to open the file...
char* filepath = "C:\\Program Files\\Microsoft Office\\Office12\\BITMAPS\\STYLES\\GLOBE.WMF";
if( !file.Open((LPCTSTR)filepath , CFile::modeRead, &fexp) )
{
fexp.ReportError();
return 1;
}
But instead if I wrote it this way, it doesn't give error:
if( !file.Open( _T("C:\\Program Files\\Microsoft Office\\Office12\\BITMAPS\\STYLES\\GLOBE.WMF") , CFile::modeRead, &fexp) )
{
fexp.ReportError();
return 1;
}
I am looking at passing a variable as the first argument to the CFile::Open() method.
The ## operator is a preprocessor concatenation operator. That is, this is valid code:
#define DECLARE_PTR(X) typedef std::auto_ptr<X> X##Ptr
DECLARE_PTR(int); // gets expanded to typedef std::auto_ptr<int> intPtr
intPtr i(new int(1));
In your case, the _T macro prepends the Long conversion symbol (L) to the input given. This only works with string literals. That means you can't write
char* str = "ABC";
wchar_t* wstr = _T(str); // error: Lstr is undefined
but you can safely write
char* str = "ABC";
LPTSTR wstr = _T("ABC"); // OK, gets expanded to wchar_t * wstr = L"ABC";
// when UNICODE is defined
// and char * wstr = "ABC"; when unicode is not defined
The L operator is a convertor of char and char* literals to a Long representation (from byte-wide representation to sizeof(wchar_t)-wide representation).
The macro is simply stringizing L with the argument so that:
_T("xyz")
becomes:
L"xyz"
This is the way to make a wstring but, in the non-Unicode versions, _T will map to nothing, so you'll get regular strings there.
_T() allows you to set up your string literals so that you can build as either Unicode or non-unicode.
In non-unicode builds it evaluates to nothing so a string literal is represented as "XYZ" which is a normal narrow string. In a unicode build it evaluates to L (L"XYZ") which tells the compiler that the string literal is a wide character string. This and the various "T" string typedefs LPCTSTR etc. Allow you to write code that builds correctly for unicode and non-unicode builds.
Note that google is your friend, simply typing _T into google gives several useful results...