howto.html: Fix example code...

2002-11-20  Jonathan Wakely  <redi@gcc.gnu.org>

	* docs/html/21_strings/howto.html: Fix example code, cite Gaby's
	explanation of "<unknown type>" error with toupper/tolower.
	* docs/html/22_locale/howto.html: Be more consistent with
	example in 21_strings.

From-SVN: r59284
This commit is contained in:
Jonathan Wakely 2002-11-20 01:12:02 +00:00
parent 27dcc451f4
commit dd768f5f25
3 changed files with 57 additions and 24 deletions

View File

@ -1,3 +1,10 @@
2002-11-20 Jonathan Wakely <redi@gcc.gnu.org>
* docs/html/21_strings/howto.html: Fix example code, cite Gaby's
explanation of "<unknown type>" error with toupper/tolower.
* docs/html/22_locale/howto.html: Be more consistent with
example in 21_strings.
2002-11-19 John Gustafsson <forgoil@rsn.bth.se>
* docs/html/20_util/howto.html: Fix typo.

View File

@ -278,19 +278,32 @@
#include &lt;algorithm&gt;
#include &lt;cctype&gt; // old &lt;ctype.h&gt;
std::string s ("Some Kind Of Initial Input Goes Here");
struct ToLower
{
char operator() (char c) const { return std::tolower(c); }
};
// Change everything into upper case
std::transform (s.begin(), s.end(), s.begin(), toupper);
struct ToUpper
{
char operator() (char c) const { return std::toupper(c); }
};
// Change everything into lower case
std::transform (s.begin(), s.end(), s.begin(), tolower);
int main()
{
std::string s ("Some Kind Of Initial Input Goes Here");
// Change everything back into upper case, but store the
// result in a different string
std::string capital_s;
capital_s.reserve(s.size());
std::transform (s.begin(), s.end(), capital_s.begin(), tolower); </pre>
// Change everything into upper case
std::transform (s.begin(), s.end(), s.begin(), ToUpper());
// Change everything into lower case
std::transform (s.begin(), s.end(), s.begin(), ToLower());
// Change everything back into upper case, but store the
// result in a different string
std::string capital_s;
capital_s.resize(s.size());
std::transform (s.begin(), s.end(), capital_s.begin(), ToUpper());
} </pre>
<p><span class="larger"><strong>Note</strong></span> that these calls all
involve the global C locale through the use of the C functions
<code>toupper/tolower</code>. This is absolutely guaranteed to work --
@ -301,19 +314,28 @@
So, if all your input forevermore consists of only those 96
characters (hahahahahaha), then you're done.
</p>
<p>At minimum, you can write short wrappers like
<p><span class="larger"><strong>Note</strong></span> that the
<code>ToUpper</code> and <code>ToLower</code> function objects
are needed because <code>toupper</code> and <code>tolower</code>
are overloaded names (declared in <code>&lt;cctype&gt;</code> and
<code>&lt;locale&gt;</code>) so the template-arguments for
<code>transform&lt;&gt;</code> cannot be deduced, as explained in
<a href="http://gcc.gnu.org/ml/libstdc++/2002-11/msg00180.html">this
message</a>. <!-- section 14.8.2.4 clause 16 in ISO 14882:1998
if you're into that sort of thing -->
At minimum, you can write short wrappers like
</p>
<pre>
char toLower (char c)
{
return tolower(static_cast&lt;unsigned char&gt;(c));
return std::tolower(c);
} </pre>
<p>The correct method is to use a facet for a particular locale
and call its conversion functions. These are discussed more in
Chapter 22; the specific part is
<a href="../22_locale/howto.html#5">here</a>, which shows the
final version of this code. (Thanks to James Kanze for assistance
and suggestions on all of this.)
<a href="../22_locale/howto.html#7">Correct Transformations</a>,
which shows the final version of this code. (Thanks to James Kanze
for assistance and suggestions on all of this.)
</p>
<p>Another common operation is trimming off excess whitespace. Much
like transformations, this task is trivial with the use of string's

View File

@ -168,18 +168,18 @@
#include &lt;algorithm&gt;
#include &lt;cctype&gt; // old &lt;ctype.h&gt;
struct Toupper
struct ToUpper
{
Toupper(std::locale const&amp; l) : loc(l) {;}
char operator() (char c) { return std::toupper(c,loc); }
ToUpper(std::locale const&amp; l) : loc(l) {;}
char operator() (char c) const { return std::toupper(c,loc); }
private:
std::locale const&amp; loc;
};
struct Tolower
struct ToLower
{
Tolower(std::locale const&amp; l) : loc(l) {;}
char operator() (char c) { return std::tolower(c,loc); }
ToLower(std::locale const&amp; l) : loc(l) {;}
char operator() (char c) const { return std::tolower(c,loc); }
private:
std::locale const&amp; loc;
};
@ -187,9 +187,9 @@
int main ()
{
std::string s("Some Kind Of Initial Input Goes Here");
std::locale loc_c("C");
Toupper up(loc_c);
Tolower down(loc_c);
std::locale loc_c("C");
ToUpper up(loc_c);
ToLower down(loc_c);
// Change everything into upper case.
std::transform(s.begin(), s.end(), s.begin(), up);
@ -202,6 +202,10 @@
std::string capital_s;
std::transform(s.begin(), s.end(), std::back_inserter(capital_s), up);
}</pre>
<p>The <code>ToUpper</code> and <code>ToLower</code> structs can be
generalized for other character types by making <code>operator()</code>
a member function template.
</p>
<p>The final version of the code uses <code>bind2nd</code> to eliminate
the wrapper structs, but the resulting code is tricky. I have not
shown it here because no compilers currently available to me will