I have an MFC application in C++ that uses std::string and std::wstring, and frequently casts from one to the other, and a whole lot of other nonsense. I need to standardize everything to a single format, so I was wondering if I should go with CString or std::wstring.
In the application, I'll need to generate strings from a string table, work with a lot of windows calls that require constant tchar or wchar_t pointers, Edit Controls, and interact with a COM object's API that requires BSTR.
I also have vectors of strings, so is there any problem with a vector of CStrings?
Which one is better? What are the pros and cons of each?
Examples
BSTR to wstring
CComBSTR tstr;
wstring album;
if( (trk->get_Info((BSTR *)&tstr)) == S_OK && tstr!= NULL)
album = (wstring)tstr;
wstring to BSTR
CComBSTR tstr = path.c_str();
if(trk->set_Info(tstr) == S_OK)
return true;
String resource to wstring
CString t;
wstring url;
t.LoadString(IDS_SCRIPTURL);
url = t;
GetProfileString() returns a CString.
integer to string format:
wchar_t total[32];
swprintf_s(total, 32, L"%d", trk->getInt());
wstring tot(total);
These are the two classes that you will actually use. std::string is used for standard ascii and utf-8 strings. std::wstring is used for wide-character/unicode (utf-16) strings. There is no built-in class for utf-32 strings (though you should be able to extend your own from basic_string if you need one).
A CString object keeps character data in a CStringData object. CString accepts NULL-terminated C-style strings. CString tracks the string length for faster performance, but it also retains the NULL character in the stored character data to support conversion to LPCWSTR .
CString is neither a C nor a C++ type.
A wide character is a computer character datatype that generally has a size greater than the traditional 8-bit character. The increased datatype size allows for the use of larger coded character sets.
std::basic_string<> (or rather its specialisations) is horrible to work with, it's imo one of the major shortcomings of the STL (and I'd say C++ in general). It doesn't even know about encodings - c'mon, this is 2010. Being able to define the size of your character isn't enough, 'cause there's no way indicate variable-size characters in a basic_string<>. Now, utf-8 isn't nice to work with with a CString, but it's not as bad as trying to do it with basic_string. While I agree with the spirit of the above posters that a standard solution is better than the alternatives, CString is (if your project uses MFC or ATL anyway) much nicer to work with than std::string/wstring: conversions between ANSI/Unicode (through CStringA and CStringW), BSTR, loading from string table, cast operators to TCHAR (.c_str()? really?), ...
CString also has Format(), which, although not safe and somewhat ugly, is convenient. If you prefer safe formatting libraries, you'll be better off with basic_string.
Furthermore, CString has some algorithms as member functions that you'll need boost string utilities for to do on basic_string such as trim, split etc.
Vectors of CString are no problem.
Guard against a dogmatic dismissal of CString on the basis of it being Windows-only: if you use it in a Windows GUI, the application is Windows-only anyway. That being said, if there's any chance that your code will need to be cross-platform in the future, you're going to be stuck with basic_string<>.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With