wxString

From WxWiki
Jump to navigation Jump to search
Official Classes SmallBlocks.png Archive Containers Controls Data Structures Database Date & Time Debug Device Contexts Dialogs Document & Views Drag & Drop Events Filesystem Frames Graphics Grid Cell Help HTML Logging Miscellaneous Networking Printing Sizers Streams Threading Windows

String class for passing textual data to or receiving it from wxWidgets.

Note: While the use of wxString is unavoidable in wxWidgets program, you are encouraged to use the standard string classes std::string or std::wstring in your applications and convert them to and from wxString only when interacting with wxWidgets.

wxString is a class representing a Unicode character string but with methods taking or returning both wchar_t wide characters and wchar_t* wide strings and traditional char characters and char* strings. The dual nature of wxString API makes it simple to use in all cases and, importantly, allows the code written for either ANSI or Unicode builds of the previous wxWidgets versions to compile and work correctly with the single unified Unicode build of wxWidgets 3.0. It is also mostly transparent when using wxString with the few exceptions described below.

Converting a wxString to a Normal String

The following works both for ANSI and Unicode. You could write simpler code for ANSI, but sooner or later you'd have to rewrite it to cope with Unicode.

If you want to pass the contents of a wxString to an external function that takes a char*, do something like:

wxString foo( wxT("Hello world") );
bool result = external_lib_function( foo.mb_str(wxConvUTF8) );

However the following won't work reliably:

wxString foo( wxT("Hello world") );
const char* ascii_str = (const char*)foo.mb_str(wxConvUTF8);

Why not? Because (in a Unicode build) wxString::mb_str returns a transient const wxCharBuffer, which goes out of scope at the semicolon. So ascii_str points to a stale block of memory that might be reallocated at any time. (In practice it seems that it usually lasts long enough to be read on Linux, but not on MSWin.)

The moral: stick to wxString for as long as possible. But if you really must convert to a char*, do something like:

wxString foo( wxT("Hello world") );
char buf[100];
strcpy( buf, (const char*)foo.mb_str(wxConvUTF8) ); // buf will now contain "Hello world"

Converting a Normal String to a wxString

For simple ASCII to wxString conversion, especially with the Unicode build:

const char *ascii_str = "Some text";
wxString string = wxString::FromAscii(ascii_str);
wxString string2 = wxString::FromAscii("another text");

or

wxString string = wxString::From8BitData(ascii_str); // since version 2.8.4

For convenience, this also works fine for both ASCII and Unicode:

const char *ascii_str = "Some text";
wxString string(ascii_str, wxConvUTF8);

or you can write a function if you have many Unicode character strings in you source:

inline wxString _U(const char String[] = "")
{
	return wxString(String, wxConvUTF8);
}

and use it as

wxMessageBox(_U("ólé"));

Converting a UTF8 wxString that Stores Each Unicode Character as Many Unicode Characters to Normal UTF8

(might be useful when (wrongly) you read UTF8 data from the Internet. It can also be read directly as UTF8.)

str = wxString(str.To8BitData(), wxConvUTF8);

Converting an Integer to wxString

To convert an integer to a wxString, you can use several methods:

wxString mynewstring = wxString::Format(_T("%d"), myoldinteger);
wxString s; s.Printf(_T("%d"), myint);
wxString mynewstring = wxString() << myoldinteger;

If you're going straight into a text control, you can skip the conversion entirely:

*textctrl << myint;

Warnings

If you get errors related to converting between char arrays/pointers and wxStrings, such as this one from gcc 3.2:

   conversion from `const char[12]' to `const wxString' is ambiguous

or this one from Microsoft Visual C++ 6:

   c:\project\yourfile.cpp(628) : error C2440: 'initializing' : cannot convert from 'char [12]' to 'class wxString'
           No constructor could take the source type, or constructor overload resolution was ambiguous

it's actually a Unicode error. You have to wrap your strings in wxT() or _() to make them compile properly in Unicode builds. So, you would change this code:

mystring("Hello World");

into this:

mystring(wxT("Hello World"));

Always wrap your strings with these macros even if you don't plan to compile for Unicode right now. It makes porting much easier later on. _() has the extra ability of supporting Internationalization, but if you don't care about that, wxT() is fine. See also: WxWidgets Source Oddities

Careful with Constants

Before adding or inserting ('<<'), you need to have a wxString object to hold the results, or you will get weird results.

For example:

the_configuration->Write( wxT("doc_file"), wxT("channels") + '/' + wxT("hello") );

will write garbage, since you can't add "channels" + '/' + "hello" with nothing to hold them. Do this:

wxString my_string;
my_string << wxT("channels") << '/' << wxT("hello");
the_configuration->Write( wxT("doc_file"), my_string );

Please note that this isn't internationalization friendly. (A better example is welcome.)

Careful with DLLs

If you are using wxWidgets both for generation of exe and dll and have a wxString truncated after its first character, check whether your development environment doesn't automatically choose Multi-Bytes for the generation of exe and Unicode for the generation of DLL. (It seems that MS Visual C++ 2005 does it).

This can cause inconsistency with wxConvCurrent as it will be different in SDK's and exe contexts.

Tokenizing

If you want to `split' your string, take a look at wxStringTokenizer.

NULL

C and C++ strings are distinct.

A C string ends with a zero-terminated character ('\0', NUL). The terminating character is not considered a part of the string.

A Pascal or MS Basic string (used in COM Automation) starts with the string length, and ends when that length is reached. These are similar to C++ Strings.

C++ Strings (STL std::string and others) contain a certain length dictated by Length() (or length()), and, unlike C strings, can contain embedded zero "termination" characters ('\0'). If you call a C string function on it like strlen(), it will give you the value if it was a C string - but really it's a C++ string - so the value from strlen() is, in fact, incorrect (due to possible embedded NULs).

-However- The current wxString is a mishmash of C and C++ strings - and most ancillary functions (a lot of other besides length, such as find()) treat it as a C string - but it could be a C++ string - and wxString::Length() treats it as a C++ string.

See Also