4

I have been working now on a project based on DirectX and I am struggling with something. Though the DirectX SDK relies heavily on Windows data types like LPSTR, LPCSTR, ... I have been using for my own classes std::string which was quite easy to work with, but it looks strange to mix both ways of handling strings. Although this is a vague question, what do you suggest - should I work with the strings or with the Windows pointers for different string types to keep some consistency?

3
  • std::string is by far easier to work with, and access to the underlying C string is only a few extra characters. That said, it's a bit more of a bother to use to interface with C in C++03 than it is in C++11. Commented Jan 31, 2013 at 21:09
  • 4
    I suggest using std::wstring on windows. See std::wstring VS std::string. Commented Jan 31, 2013 at 21:14
  • Please read: utf8everywhere.org/#how Commented Jan 31, 2013 at 21:28

3 Answers 3

5

LPSTR is just an alias for char* and LCPSTR is an alias for const char*, so your question actually sounds like "Should I use C++ strings or C strings?"

Well, C++ std::string has a member function called c_str() (or the equivalent data() function for STL compatibility) that returns a (non-modifiable) C string. So any time a function accepts an LPCTSTR, you can provide the output of c_str() as an argument.

I suggest you working with C++ std::string whenever you can, it is safer.

Sign up to request clarification or add additional context in comments.

7 Comments

For completeness sake, .data() or &str[0] to get char*.
@Rapptz: writing to the buffer returned by data() and c_str() is UB though. Also, to the best of my knowledge, they both return const char*
I know that the Windows data types are just C strings yet I wanted to see how other people handle this mix of "real C++" code and these historical relicts used throughout the WinAPI. Thanks though for your suggestion.
@AndyProwl &str[0] is what I'm used to. i.e. char* str2 = &str[0];. I admit I'm not sure if data() returns a const char* or a char*.
@Rapptz, I hope my question helps clear up some missing knowledge in that area. You can use &str[0] to modify the buffer as long as you don't bump into the null terminator, and data() and c_str() are equivalent. Also note that all of this ease only comes with C++11, where string buffers have to have contiguous characters.
|
2

In modern C++ code, I would just use a robust string class like std::string, or better std::wstring for Unicode UTF-16 support with Windows. Then, you can convert to "raw" C strings at the API boundaries.

To get a read-only "raw" C string pointer, you can use std::[w]string::c_str() method.

Instead, if you want to modify std::[w]string buffer, you can first call the .resize() method to prepare the string buffer, making it big enough; then you can use &str[0] to access the internal buffer for those APIs than need to write into it.

Note that on Windows specific code, ATL's CString is another convenient string class you may want to use. It has some platform-specific convenient facilities, like loading string from resources (which is good for app localization).

Since CString offers an implicit conversion to LPCTSTR, you can just pass CString instances to APIs expecting a raw LPCTSTR. Instead, if you need to modify the internal CString buffer, you can use GetBuffer()/ReleaseBuffer() methods.

Comments

1

Building on @Andy Prowl's answer, you might want to code everything using "T" strings (i.e. LPTSTR instead of LPSTR or LPWSTR). The exact type of T (really TCHAR) is set at compile time based on whether you have UNICODE and _UNICODE #defined. This gives you compatibility with both.

You can still use C++ strings with this technique by deriving a tstring class from basic_string<>:

typedef std::basic_string<TCHAR> tstring;

4 Comments

On modern Win32 C++ code, I'd just use UTF-16 on Windows (UTF-8 is OK outside app boundaries), and just use std::wstring and wchar_t (or CString in Unicode builds, corresponding to CStringW), instead of the old ANSI/MBCS-compatible TCHAR model. I consider the TCHAR model something obsolete and useless in modern days.
Good point. +1. But speaking of modern days, what about Win32 and DirectX? Haven't newer languages (C#) and APIs (WPF) passed them by, too? BTW, the irony of @Mr.C64 talking about obsolescence is not lost on me. :)
Saying Passed them by doesn't make sense because those newer technologies are built on top of the older ones. They are still in great use today. However, TCHAR has little use other than for old code bases or backwards compatibility.
Ouch! Don't use TCHAR. Not unless you need to support Windows 98.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.