views:

938

answers:

6

OR How to not kill yourself or someone the next time the C++ compiler twists your arm to convert between 2 arbitrary string types just to mess with you?

I have a tough time coding in C++ since I am used to VB6, C#, Ruby, for string operations. But now I've spent over 30 mins trying to log a string containing 2 guids and a string to the debug window... and it isn't getting any easier And I've already met RPC_WSTR, std::wstring and LPCWSTR

Are there simple (or any) rules to know the conversions between them? Or does it only come after years of torture?

Basically I'm looking for the most frequently used string types in both standard APIs and MS-specific/Visual C++ libraries ; What to do the next time, i see

Error   8 error C2664: 'OutputDebugStringW' : cannot convert parameter 1 from 'std::wstring' to 'LPCWSTR'

Update: I fixed the ^^^^ compile error. I am looking for a more global answer not for the solution for specific issue I listed as an example.

+2  A: 

Here is a article that covers thing you need mainly for CString

yesraaj
A: 

Welcome to C++ ;-)

You can just create a wrapper function that accepts a std::string. Then in the function extract the c-style string and pass to OutputDebugStringW.

20th Century Boy
for MFC windows world right
yesraaj
+1  A: 
OutputDebugStringW (myString.c_str ());
jon hanson
A: 

std::wstring and std::string are just aliases for std::basic_string<wchar_t> and std::basic_string<char>.

Both have a .c_str()-method which returns a conventional C-string pointer (LPCWSTR etc.) and a constructor that takes a C-string.

Dario
+8  A: 

There are two built-in string types:

  • C++ strings use the std::string class (std::wstring for wide characters)
  • C-style strings are const char pointers const char*) (or const wchar_t*)

Both can be used in C++ code. Most API's, including Windows' are written in C, and so they use char pointers rather than the std::string class.

Microsoft further hides these pointers behind a number of macros.

LPCWSTR is a Long Pointer to a Const Wide String, or in other words, a const wchar_t*. LPSTR is a Long Pointer String, or in other words, a char*. (not const)

They have a handful more, but they should be pretty easy to guess once you know these first few. They also have *TSTR variants, where the T is used to indicate that this might be either regular or wide chars, depending on whether UNICODE is enabled in the project. LPCTSTR resolves to LPCWSTR if UNICODE is defined, and LPCSTR otherwise.

So really, when working with strings, you just need to know the two types I listed at the top. The rest are just macros for various variants of the char pointer version.

Converting from a char pointer to a string is simple:

const char* cstr = "hello world";
std::string cppstr = cstr;

And the other way isn't much hader:

std::string cppstr("hello world");
const char* cstr = cppstr.c_str();

That is, std::string takes a C-style string as an argument in the constructor. And it has a c_str() member function that returns a C-style string.

Some commonly used libraries define their own string types, and in those cases, you'll have to check the documentation for how they interoperate with the "proper" string classes.

You should usually prefer the C++ std::string class, as, unlike char pointers, they behave as strings. For example:

std:string a = "hello ";
std:string b = "world";
std:string c = a + b; // c now contains "hello world"

const char* a = "hello ";
const char* b = "world";
const char* c = a + b; // error, you can't add two pointers

std:string a = "hello worl";
char b = 'd';
std:string c = a + b; // c now contains "hello world"

const char* a = "hello worl";
char b = 'd';
const char* c = a + b; // Doesn't cause an error, but won't do what you expect either. the char 'd' is converted to an int, and added to the pointer `a`. You're doing pointer arithmetic rather than string manipulation.
jalf
+1 Thanks... that made some sense to me.
Gishu
A: 

You might want to look at CStdString. It's a cross platform standard C++ CString implementation that converts to most other string types pretty easily. Makes almost all string related headaches go away and it's just one header file.

drby