]>
Commit | Line | Data |
---|---|---|
a660d684 KB |
1 | \section{wxString overview}\label{wxstringoverview} |
2 | ||
9e2be6f0 | 3 | Classes: \helpref{wxString}{wxstring}, \helpref{wxArrayString}{wxarraystring}, \helpref{wxStringTokenizer}{wxstringtokenizer} |
a660d684 | 4 | |
99f09bc1 VZ |
5 | \subsection{Introduction} |
6 | ||
532372a3 JS |
7 | wxString is a class which represents a character string of arbitrary length (limited by |
8 | {\it MAX\_INT} which is usually 2147483647 on 32 bit machines) and containing | |
9 | arbitrary characters. The ASCII NUL character is allowed, although care should be | |
10 | taken when passing strings containing it to other functions. | |
99f09bc1 | 11 | |
d9a50173 VZ |
12 | wxString works with both ASCII (8 bit characters) as well as UNICODE (16 but |
13 | characters) strings. | |
99f09bc1 | 14 | |
532372a3 | 15 | This class has all the standard operations you can expect to find in a string class: |
f6bcfd97 | 16 | dynamic memory management (string extends to accommodate new characters), |
99f09bc1 | 17 | construction from other strings, C strings and characters, assignment operators, |
532372a3 | 18 | access to individual characters, string concatenation and comparison, substring |
99f09bc1 VZ |
19 | extraction, case conversion, trimming and padding (with spaces), searching and |
20 | replacing and both C-like \helpref{Printf()}{wxstringprintf} and stream-like | |
532372a3 JS |
21 | insertion functions as well as much more - see \helpref{wxString}{wxstring} |
22 | for a list of all functions. | |
99f09bc1 VZ |
23 | |
24 | \subsection{Comparison of wxString to other string classes} | |
25 | ||
26 | The advantages of using a special string class instead of working directly with | |
532372a3 JS |
27 | C strings are so obvious that there is a huge number of such classes available. |
28 | The most important advantage is the need to always | |
ed93168b VZ |
29 | remember to allocate/free memory for C strings; working with fixed size buffers almost |
30 | inevitably leads to buffer overflows. At last, C++ has a standard string class | |
31 | (std::string). So why the need for wxString? | |
99f09bc1 VZ |
32 | |
33 | There are several advantages: | |
34 | ||
35 | \begin{enumerate}\itemsep=0pt | |
40b480c3 | 36 | \item {\bf Efficiency} This class was made to be as efficient as possible: both |
532372a3 JS |
37 | in terms of size (each wxString objects takes exactly the same space as a {\it |
38 | char *} pointer, sing \helpref{reference counting}{wxstringrefcount}) and speed. | |
99f09bc1 VZ |
39 | It also provides performance \helpref{statistics gathering code}{wxstringtuning} |
40 | which may be enabled to fine tune the memory allocation strategy for your | |
40b480c3 JS |
41 | particular application - and the gain might be quite big. |
42 | \item {\bf Compatibility} This class tries to combine almost full compatibility | |
99f09bc1 | 43 | with the old wxWindows 1.xx wxString class, some reminiscence to MFC CString |
532372a3 | 44 | class and 90\% of the functionality of std::string class. |
40b480c3 | 45 | \item {\bf Rich set of functions} Some of the functions present in wxString are |
99f09bc1 VZ |
46 | very useful but don't exist in most of other string classes: for example, |
47 | \helpref{AfterFirst}{wxstringafterfirst}, | |
fd34e3a5 | 48 | \helpref{BeforeLast}{wxstringbeforelast}, \helpref{operator<<}{wxstringoperatorout} |
99f09bc1 | 49 | or \helpref{Printf}{wxstringprintf}. Of course, all the standard string |
40b480c3 | 50 | operations are supported as well. |
532372a3 JS |
51 | \item {\bf UNICODE} In this release, wxString only supports {\it construction} from |
52 | a UNICODE string, but in the next one it will be capable of also storing its | |
40b480c3 JS |
53 | internal data in either ASCII or UNICODE format. |
54 | \item {\bf Used by wxWindows} And, of course, this class is used everywhere | |
99f09bc1 VZ |
55 | inside wxWindows so there is no performance loss which would result from |
56 | conversions of objects of any other string class (including std::string) to | |
40b480c3 | 57 | wxString internally by wxWindows. |
99f09bc1 VZ |
58 | \end{enumerate} |
59 | ||
60 | However, there are several problems as well. The most important one is probably | |
61 | that there are often several functions to do exactly the same thing: for | |
62 | example, to get the length of the string either one of | |
f6bcfd97 BP |
63 | length(), \helpref{Len()}{wxstringlen} or |
64 | \helpref{Length()}{wxstringlength} may be used. The first function, as almost | |
99f09bc1 VZ |
65 | all the other functions in lowercase, is std::string compatible. The second one |
66 | is "native" wxString version and the last one is wxWindows 1.xx way. So the | |
67 | question is: which one is better to use? And the answer is that: | |
68 | ||
69 | {\bf The usage of std::string compatible functions is strongly advised!} It will | |
70 | both make your code more familiar to other C++ programmers (who are supposed to | |
71 | have knowledge of std::string but not of wxString), let you reuse the same code | |
72 | in both wxWindows and other programs (by just typedefing wxString as std::string | |
73 | when used outside wxWindows) and by staying compatible with future versions of | |
74 | wxWindows which will probably start using std::string sooner or later too. | |
75 | ||
f6bcfd97 | 76 | In the situations where there is no corresponding std::string function, please |
99f09bc1 | 77 | try to use the new wxString methods and not the old wxWindows 1.xx variants |
532372a3 | 78 | which are deprecated and may disappear in future versions. |
99f09bc1 | 79 | |
40b480c3 | 80 | \subsection{Some advice about using wxString}\label{wxstringadvices} |
99f09bc1 | 81 | |
40b480c3 | 82 | Probably the main trap with using this class is the implicit conversion operator to |
99f09bc1 | 83 | {\it const char *}. It is advised that you use \helpref{c\_str()}{wxstringcstr} |
532372a3 | 84 | instead to clearly indicate when the conversion is done. Specifically, the |
99f09bc1 VZ |
85 | danger of this implicit conversion may be seen in the following code fragment: |
86 | ||
87 | \begin{verbatim} | |
99f09bc1 VZ |
88 | // this function converts the input string to uppercase, output it to the screen |
89 | // and returns the result | |
90 | const char *SayHELLO(const wxString& input) | |
91 | { | |
92 | wxString output = input.Upper(); | |
93 | ||
94 | printf("Hello, %s!\n", output); | |
95 | ||
96 | return output; | |
97 | } | |
99f09bc1 VZ |
98 | \end{verbatim} |
99 | ||
40b480c3 | 100 | There are two nasty bugs in these three lines. First of them is in the call to the |
99f09bc1 | 101 | {\it printf()} function. Although the implicit conversion to C strings is applied |
40b480c3 | 102 | automatically by the compiler in the case of |
99f09bc1 VZ |
103 | |
104 | \begin{verbatim} | |
105 | puts(output); | |
106 | \end{verbatim} | |
107 | ||
40b480c3 JS |
108 | because the argument of {\it puts()} is known to be of the type {\it const char *}, |
109 | this is {\bf not} done for {\it printf()} which is a function with variable | |
99f09bc1 VZ |
110 | number of arguments (and whose arguments are of unknown types). So this call may |
111 | do anything at all (including displaying the correct string on screen), although | |
112 | the most likely result is a program crash. The solution is to use | |
113 | \helpref{c\_str()}{wxstringcstr}: just replace this line with | |
114 | ||
115 | \begin{verbatim} | |
116 | printf("Hello, %s!\n", output.c_str()); | |
117 | \end{verbatim} | |
118 | ||
119 | The second bug is that returning {\it output} doesn't work. The implicit cast is | |
120 | used again, so the code compiles, but as it returns a pointer to a buffer | |
121 | belonging to a local variable which is deleted as soon as the function exits, | |
122 | its contents is totally arbitrary. The solution to this problem is also easy: | |
532372a3 | 123 | just make the function return wxString instead of a C string. |
99f09bc1 VZ |
124 | |
125 | This leads us to the following general advice: all functions taking string | |
126 | arguments should take {\it const wxString\&} (this makes assignment to the | |
127 | strings inside the function faster because of | |
128 | \helpref{reference counting}{wxstringrefcount}) and all functions returning | |
129 | strings should return {\it wxString} - this makes it safe to return local | |
130 | variables. | |
131 | ||
132 | \subsection{Other string related functions and classes} | |
133 | ||
7ae8ee14 VZ |
134 | As most programs use character strings, the standard C library provides quite |
135 | a few functions to work with them. Unfortunately, some of them have rather | |
136 | counter-intuitive behaviour (like strncpy() which doesn't always terminate the | |
137 | resulting string with a NULL) and are in general not very safe (passing NULL | |
138 | to them will probably lead to program crash). Moreover, some very useful | |
139 | functions are not standard at all. This is why in addition to all wxString | |
140 | functions, there are also a few global string functions which try to correct | |
141 | these problems: \helpref{wxIsEmpty()}{wxisempty} verifies whether the string | |
f47658bb | 142 | is empty (returning {\tt TRUE} for {\tt NULL} pointers), |
7ae8ee14 VZ |
143 | \helpref{wxStrlen()}{wxstrlen} also handles NULLs correctly and returns 0 for |
144 | them and \helpref{wxStricmp()}{wxstricmp} is just a platform-independent | |
145 | version of case-insensitive string comparison function known either as | |
146 | stricmp() or strcasecmp() on different platforms. | |
99f09bc1 | 147 | |
378b05f7 VZ |
148 | The {\tt <wx/string.h>} header also defines \helpref{wxSnprintf}{wxsnprintf} |
149 | and \helpref{wxVsnprintf}{wxvsnprintf} functions which should be used instead | |
150 | of the inherently dangerous standard {\tt sprintf()} and which use {\tt | |
151 | snprintf()} instead which does buffer size checks whenever possible. Of | |
152 | course, you may also use \helpref{wxString::Printf}{wxstringprintf} which is | |
153 | also safe. | |
154 | ||
99f09bc1 VZ |
155 | There is another class which might be useful when working with wxString: |
156 | \helpref{wxStringTokenizer}{wxstringtokenizer}. It is helpful when a string must | |
40b480c3 | 157 | be broken into tokens and replaces the standard C library {\it |
99f09bc1 VZ |
158 | strtok()} function. |
159 | ||
9e2be6f0 | 160 | And the very last string-related class is \helpref{wxArrayString}{wxarraystring}: it |
40b480c3 | 161 | is just a version of the "template" dynamic array class which is specialized to work |
532372a3 JS |
162 | with strings. Please note that this class is specially optimized (using its |
163 | knowledge of the internal structure of wxString) for storing strings and so it is | |
164 | vastly better from a performance point of view than a wxObjectArray of wxStrings. | |
99f09bc1 VZ |
165 | |
166 | \subsection{Reference counting and why you shouldn't care about it}\label{wxstringrefcount} | |
167 | ||
168 | wxString objects use a technique known as {\it copy on write} (COW). This means | |
169 | that when a string is assigned to another, no copying really takes place: only | |
532372a3 | 170 | the reference count on the shared string data is incremented and both strings |
99f09bc1 VZ |
171 | share the same data. |
172 | ||
173 | But as soon as one of the two (or more) strings is modified, the data has to be | |
174 | copied because the changes to one of the strings shouldn't be seen in the | |
f6bcfd97 | 175 | others. As data copying only happens when the string is written to, this is |
99f09bc1 VZ |
176 | known as COW. |
177 | ||
178 | What is important to understand is that all this happens absolutely | |
179 | transparently to the class users and that whether a string is shared or not is | |
180 | not seen from the outside of the class - in any case, the result of any | |
181 | operation on it is the same. | |
182 | ||
183 | Probably the unique case when you might want to think about reference | |
184 | counting is when a string character is taken from a string which is not a | |
185 | constant (or a constant reference). In this case, due to C++ rules, the | |
186 | "read-only" {\it operator[]} (which is the same as | |
ed93168b | 187 | \helpref{GetChar()}{wxstringgetchar}) cannot be chosen and the "read/write" |
99f09bc1 VZ |
188 | {\it operator[]} (the same as |
189 | \helpref{GetWritableChar()}{wxstringgetwritablechar}) is used instead. As the | |
190 | call to this operator may modify the string, its data is unshared (COW is done) | |
191 | and so if the string was really shared there is some performance loss (both in | |
192 | terms of speed and memory consumption). In the rare cases when this may be | |
193 | important, you might prefer using \helpref{GetChar()}{wxstringgetchar} instead | |
532372a3 JS |
194 | of the array subscript operator for this reasons. Please note that |
195 | \helpref{at()}{wxstringat} method has the same problem as the subscript operator in | |
99f09bc1 VZ |
196 | this situation and so using it is not really better. Also note that if all |
197 | string arguments to your functions are passed as {\it const wxString\&} (see the | |
40b480c3 | 198 | section \helpref{Some advice}{wxstringadvices}) this situation will almost |
99f09bc1 VZ |
199 | never arise because for constant references the correct operator is called automatically. |
200 | ||
201 | \subsection{Tuning wxString for your application}\label{wxstringtuning} | |
202 | ||
203 | \normalbox{{\bf Note:} this section is strictly about performance issues and is | |
204 | absolutely not necessary to read for using wxString class. Please skip it unless | |
205 | you feel familiar with profilers and relative tools. If you do read it, please | |
206 | also read the preceding section about | |
ed93168b | 207 | \helpref{reference counting}{wxstringrefcount}.} |
99f09bc1 VZ |
208 | |
209 | For the performance reasons wxString doesn't allocate exactly the amount of | |
210 | memory needed for each string. Instead, it adds a small amount of space to each | |
532372a3 | 211 | allocated block which allows it to not reallocate memory (a relatively |
99f09bc1 VZ |
212 | expensive operation) too often as when, for example, a string is constructed by |
213 | subsequently adding one character at a time to it, as for example in: | |
214 | ||
215 | \begin{verbatim} | |
99f09bc1 VZ |
216 | // delete all vowels from the string |
217 | wxString DeleteAllVowels(const wxString& original) | |
218 | { | |
219 | wxString result; | |
220 | ||
221 | size_t len = original.length(); | |
222 | for ( size_t n = 0; n < len; n++ ) | |
223 | { | |
224 | if ( strchr("aeuio", tolower(original[n])) == NULL ) | |
225 | result += original[n]; | |
226 | } | |
227 | ||
228 | return result; | |
229 | } | |
99f09bc1 VZ |
230 | \end{verbatim} |
231 | ||
40b480c3 | 232 | This is quite a common situation and not allocating extra memory at all would |
99f09bc1 VZ |
233 | lead to very bad performance in this case because there would be as many memory |
234 | (re)allocations as there are consonants in the original string. Allocating too | |
235 | much extra memory would help to improve the speed in this situation, but due to | |
236 | a great number of wxString objects typically used in a program would also | |
237 | increase the memory consumption too much. | |
238 | ||
239 | The very best solution in precisely this case would be to use | |
240 | \helpref{Alloc()}{wxstringalloc} function to preallocate, for example, len bytes | |
241 | from the beginning - this will lead to exactly one memory allocation being | |
242 | performed (because the result is at most as long as the original string). | |
243 | ||
244 | However, using Alloc() is tedious and so wxString tries to do its best. The | |
245 | default algorithm assumes that memory allocation is done in granularity of at | |
246 | least 16 bytes (which is the case on almost all of wide-spread platforms) and so | |
247 | nothing is lost if the amount of memory to allocate is rounded up to the next | |
248 | multiple of 16. Like this, no memory is lost and 15 iterations from 16 in the | |
249 | example above won't allocate memory but use the already allocated pool. | |
250 | ||
251 | The default approach is quite conservative. Allocating more memory may bring | |
252 | important performance benefits for programs using (relatively) few very long | |
253 | strings. The amount of memory allocated is configured by the setting of {\it | |
254 | EXTRA\_ALLOC} in the file string.cpp during compilation (be sure to understand | |
255 | why its default value is what it is before modifying it!). You may try setting | |
256 | it to greater amount (say twice nLen) or to 0 (to see performance degradation | |
257 | which will follow) and analyse the impact of it on your program. If you do it, | |
258 | you will probably find it helpful to also define WXSTRING\_STATISTICS symbol | |
259 | which tells the wxString class to collect performance statistics and to show | |
260 | them on stderr on program termination. This will show you the average length of | |
261 | strings your program manipulates, their average initial length and also the | |
262 | percent of times when memory wasn't reallocated when string concatenation was | |
f6bcfd97 | 263 | done but the already preallocated memory was used (this value should be about |
99f09bc1 VZ |
264 | 98\% for the default allocation policy, if it is less than 90\% you should |
265 | really consider fine tuning wxString for your application). | |
266 | ||
267 | It goes without saying that a profiler should be used to measure the precise | |
268 | difference the change to EXTRA\_ALLOC makes to your program. | |
bd0df01f | 269 |