Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which wide-character string structure do I use? CString vs wstring

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);
like image 840
Vanwaril Avatar asked Jan 03 '10 15:01

Vanwaril


People also ask

Should I use string or Wstring?

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).

What is CString used for?

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 .

Is CString C or C++?

CString is neither a C nor a C++ type.

What is a wide character C?

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.


1 Answers

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<>.

like image 56
Roel Avatar answered Oct 29 '22 17:10

Roel