Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

toupper for string?

4 views
Skip to first unread message

Terje Innerdal

unread,
Oct 14, 2000, 3:00:00 AM10/14/00
to
Is there a function that changes an entire string into capital letters,
like toupper(), but for a string.

Terje Innerdal


yoha...@my-deja.com

unread,
Oct 14, 2000, 3:00:00 AM10/14/00
to
In article <39E83E05...@dph.no>,

Probably (yes), but an STL (I think not).
But it愀 very easy to implement:

#include <string>
#include <cctype>

std::string toupper( std::string s )
{
for ( int i = 0; i < s.length(); i++ )
s[i] = std::toupper( s[i] );
return s;
}

I hope this helps,

Johann


Sent via Deja.com http://www.deja.com/
Before you buy.

Josh Sebastian

unread,
Oct 14, 2000, 3:00:00 AM10/14/00
to
My news server is crapping out, so if this comes out as a double-post,
I apologize.

In article <39E83E05...@dph.no>,
Terje Innerdal <inn...@dph.no> wrote:
> Is there a function that changes an entire string into capital
letters,
> like toupper(), but for a string.

Not exactly. But witness the power of STL:

#include <algorithm>
#include <string>
#include <cctype>
#include <iostream>

int main()
{
std::string s = "Hello, world!";
std::transform(s.begin(), s.end(), s.begin(), std::toupper);
std::cout << s << std::endl;
return 0;
}

_______

"Yields falsehood when preceded by its quotation" yields falsehood when
preceded by its quotation.

Terje Innerdal

unread,
Oct 14, 2000, 3:00:00 AM10/14/00
to
Thank You, guys!

/T

yoha...@my-deja.com wrote:

> In article <39E83E05...@dph.no>,
> Terje Innerdal <inn...@dph.no> wrote:
> > Is there a function that changes an entire string into capital
> > letters,
> > like toupper(), but for a string.
> >

> > Terje Innerdal
> >
> >
>
> Probably (yes), but an STL (I think not).
> But it愀 very easy to implement:
>
> #include <string>
> #include <cctype>
>
> std::string toupper( std::string s )
> {
> for ( int i = 0; i < s.length(); i++ )
> s[i] = std::toupper( s[i] );
> return s;
> }
>
> I hope this helps,
>
> Johann
>

Dietmar Kuehl

unread,
Oct 17, 2000, 3:00:00 AM10/17/00
to
Hi,
Josh Sebastian (tar_c...@my-deja.com) wrote:
: Not exactly. But witness the power of STL:

: #include <algorithm>
: #include <string>
: #include <cctype>
: #include <iostream>

: int main()
: {
: std::string s = "Hello, world!";
: std::transform(s.begin(), s.end(), s.begin(), std::toupper);

The above line should read

std::transform(s.begin(), s.end(), s.begin(),
static_cast<int(*)(int)>(std::toupper));

to resolve the ambiguity between 'int std::toupper(int)' and
'char std::toupper(std::locale const&, char)'.

: std::cout << s << std::endl;
: return 0;
: }
--
<mailto:dietma...@yahoo.de>
<http://www.fmi.uni-konstanz.de/~kuehl/>
I am a realistic optimist - that's why I appear to be slightly pessimistic

Tom

unread,
Oct 17, 2000, 3:00:00 AM10/17/00
to
On 17 Oct 2000 15:49:02 GMT, ku...@ramsen.informatik.uni-konstanz.de
(Dietmar Kuehl) wrote:

>Hi,
>Josh Sebastian (tar_c...@my-deja.com) wrote:
>: Not exactly. But witness the power of STL:
>
>: #include <algorithm>
>: #include <string>
>: #include <cctype>
>: #include <iostream>
>
>: int main()
>: {
>: std::string s = "Hello, world!";
>: std::transform(s.begin(), s.end(), s.begin(), std::toupper);
>
>The above line should read
>
> std::transform(s.begin(), s.end(), s.begin(),
> static_cast<int(*)(int)>(std::toupper));
>
>to resolve the ambiguity between 'int std::toupper(int)' and
>'char std::toupper(std::locale const&, char)'.

But isn't that undefined behaviour if char is signed and a character
of s is <0?

Tom

Dietmar Kuehl

unread,
Oct 17, 2000, 3:00:00 AM10/17/00
to
Hi,
Tom (the...@my-deja.com) wrote:
: On 17 Oct 2000 15:49:02 GMT, ku...@ramsen.informatik.uni-konstanz.de
: (Dietmar Kuehl) wrote:
: >The above line should read

: >
: > std::transform(s.begin(), s.end(), s.begin(),
: > static_cast<int(*)(int)>(std::toupper));
: >
: >to resolve the ambiguity between 'int std::toupper(int)' and
: >'char std::toupper(std::locale const&, char)'.

: But isn't that undefined behaviour if char is signed and a character
: of s is <0?

The original version isn't even supposed to compile, that is, my point
was the ambiguity between the two 'toupper()' functions... However, it
is correct, that this function is only defined for values representable
as 'unsigned char'. A better approach is probably to use the
'std::locale' version of the function. However, under the current rules
of the standard I think it cannot made to work without hacking a small
function or class because at some point it attempts to create a
reference to a reference. This can be fixed using type traits which
basically remove the duplicate reference but this is not required by
the current standard.

Tom

unread,
Oct 17, 2000, 3:00:00 AM10/17/00
to
On 17 Oct 2000 17:08:20 GMT, ku...@ramsen.informatik.uni-konstanz.de
(Dietmar Kuehl) wrote:

>Hi,
>Tom (the...@my-deja.com) wrote:
>: On 17 Oct 2000 15:49:02 GMT, ku...@ramsen.informatik.uni-konstanz.de
>: (Dietmar Kuehl) wrote:
>: >The above line should read
>: >
>: > std::transform(s.begin(), s.end(), s.begin(),
>: > static_cast<int(*)(int)>(std::toupper));
>: >
>: >to resolve the ambiguity between 'int std::toupper(int)' and
>: >'char std::toupper(std::locale const&, char)'.
>
>: But isn't that undefined behaviour if char is signed and a character
>: of s is <0?
>
>The original version isn't even supposed to compile, that is, my point
>was the ambiguity between the two 'toupper()' functions... However, it
>is correct, that this function is only defined for values representable
>as 'unsigned char'. A better approach is probably to use the
>'std::locale' version of the function. However, under the current rules
>of the standard I think it cannot made to work without hacking a small
>function or class because at some point it attempts to create a
>reference to a reference. This can be fixed using type traits which
>basically remove the duplicate reference but this is not required by
>the current standard.

We had a fun discussion about this in comp.lang.c++.moderated the
other day - people were describing my "boost"ed code (to do the in
place string toupper) as ridiculously unreadable, and they were
probably right.

Do you think there are any benefits to such code over a simple for
loop, or perhaps just writing the function?

Tom

Dietmar Kuehl

unread,
Oct 17, 2000, 3:00:00 AM10/17/00
to
Hi,
Tom (the...@my-deja.com) wrote:
: Do you think there are any benefits to such code over a simple for

: loop, or perhaps just writing the function?

I'd expect

std::deque<char> str;
// initialize 'str' with some length string
std::transform(str.begin(), str.end(), str.begin(),
some_functor_doing_the_transformation_basically_inline);

to be *much* faster (eg. twice as fast) than a simple loop doing the
same transformation with a good implementation of the standard C++
library. There is probably no real difference for 'std::vector',
'std::string', etc. The trick is that the standard library can (and a
good one will) provide optimized versions of the algorithms doing eg.
some counter and test hoisting.

The question is basically how complex the functor is. In the template
workshop of the netobject-days last week I have seen a pretty approach
to lambdas in C++ which provides a simple to use approach to such
things in general although a "corrected" version of 'std::bind2nd()'
should provide a reasonable approach for this specific case.

Lots of words for a simple statement: I think the algorithm approach is
the way to go. I'm not doing it as consequent as I should myself but
I'm getting better at it.

Tom

unread,
Oct 17, 2000, 3:00:00 AM10/17/00
to
On 17 Oct 2000 19:09:27 GMT, ku...@ramsen.informatik.uni-konstanz.de
(Dietmar Kuehl) wrote:

>Hi,
>Tom (the...@my-deja.com) wrote:
>: Do you think there are any benefits to such code over a simple for
>: loop, or perhaps just writing the function?
>
>I'd expect
>
> std::deque<char> str;
> // initialize 'str' with some length string
> std::transform(str.begin(), str.end(), str.begin(),
> some_functor_doing_the_transformation_basically_inline);
>
>to be *much* faster (eg. twice as fast) than a simple loop doing the
>same transformation with a good implementation of the standard C++
>library. There is probably no real difference for 'std::vector',
>'std::string', etc. The trick is that the standard library can (and a
>good one will) provide optimized versions of the algorithms doing eg.
>some counter and test hoisting.
>
>The question is basically how complex the functor is. In the template
>workshop of the netobject-days last week I have seen a pretty approach
>to lambdas in C++ which provides a simple to use approach to such
>things in general although a "corrected" version of 'std::bind2nd()'
>should provide a reasonable approach for this specific case.
>
>Lots of words for a simple statement: I think the algorithm approach is
>the way to go. I'm not doing it as consequent as I should myself but
>I'm getting better at it.

This was the code in question:

#include <algorithm>
#include <iostream>
#include <locale>
#include <boost/functional.hpp>

int main()
{
using namespace std;
string s = "HeLLo";
transform(s.begin(), s.end(), s.begin(),
boost::bind2nd(boost::ptr_fun(static_cast<char (*)(char, const
locale&)>(&std::toupper)), locale()));
cout << s;
cin.get();
}

Inlined I imagine that doesn't come to very much code, and looks a
whole lot less complicated.

Does any lib yet provide optimizations of the kind you're describing?
Other than your iostream iterator ones that is?

Tom

Dietmar Kuehl

unread,
Oct 17, 2000, 3:00:00 AM10/17/00
to
Hi,
Tom (the...@my-deja.com) wrote:
: Does any lib yet provide optimizations of the kind you're describing?

: Other than your iostream iterator ones that is?

None I'm aware of, including mine: The specific optimization would go
into the algorithms which would take care of segments. I have started
implementing the algorithms but this is not high priority. The initial
idea for the abstraction of segmented iterator comes from Matt Austern
(I had applied the optimization to certain uses of stream iterators but
haven't seen the bigger context of general segmented sequences). He has
not done this for SGI STL as far as I know although I could demonstrate
a reasonably easy to use interface which saves about 60% computing time
for simple algorithms like 'std::copy()'.

The current state is still that most implementations struggle to get
conforming (libstdc++, RogueWave, ObjectSpace, mine) or are not
maintained by someone who does this fulltime (SGI STL/STLport). There
is basically only one implementation which is already complete and
maintained full time (Dinkumware - at least it is my understanding that
it is maintained full time). ... and I'm not particularily happy with
the performance of this implementation but then I can't tell what
improvements have been made recently.

If there is interest I can try to post a more or less complete extract
implementing eg. 'transform()' making use of the optimization
demonstrating it on, say, the STLport 'std::deque' iterator (ie. the
optimization works for STLport 'std::deque', otherwise the "normal"
implementation is used).

Tom

unread,
Oct 17, 2000, 3:00:00 AM10/17/00
to
On 17 Oct 2000 21:57:37 GMT, ku...@ramsen.informatik.uni-konstanz.de
(Dietmar Kuehl) wrote:

>If there is interest I can try to post a more or less complete extract
>implementing eg. 'transform()' making use of the optimization
>demonstrating it on, say, the STLport 'std::deque' iterator (ie. the
>optimization works for STLport 'std::deque', otherwise the "normal"
>implementation is used).

If you posted the code on the moderated group, it might generate some
interest - perhaps some (currently uninvolved) people might have a go
at implementing the optimizations for stlport or the developing
libstdc++3...

Incidently, why are you coding your own std lib rather than throwing
your weight behind STLport or libstdc++? Do you prefer working alone
or did you decide that starting from scratch (apart from the SGI stl
bit) would be easier?

Tom

Dietmar Kuehl

unread,
Oct 17, 2000, 3:00:00 AM10/17/00
to
Hi,
Tom (the...@my-deja.com) wrote:
: If you posted the code on the moderated group, it might generate some

: interest - perhaps some (currently uninvolved) people might have a go
: at implementing the optimizations for stlport or the developing
: libstdc++3...

Yes, might interesting. I will try to get a reasonable extract
together. It might be interesting to discuss this stuff next week in
Toronto, too. Actually, I have some other issues regarding
standardization of how generic algorithms are implemented...

: Incidently, why are you coding your own std lib rather than throwing


: your weight behind STLport or libstdc++? Do you prefer working alone
: or did you decide that starting from scratch (apart from the SGI stl
: bit) would be easier?

When I started to work on my IOStreams, SGI was apparently not working
on this stuff, at least not in public. libstdc++ had a too restrictive
license at that time (basically I could not use my own code in my
commercial work unless I would have been the only person working on it
and thus holding the copyright) and in addition the libstdc++ was/is(?)
dominated by someone having *very* different ideas how to correctly
implement the C/C++ standard libraries. I have considered joining
forces with libstdc++ but finally decided against it.

Actually, my first release and/or some arguments I sent to Matt
basically at the same time made SGI release the IOStream/locale part of
their library to the public: That is, when I had something already
working, SGI released their implementation. I looked into integrating
with their library but found lots of things which are rather different.

Basically, I consider my current implementation as an experimentation
base for an high performance implementation: Having no customer has the
disadvantage having low funding but has the rather large advantage of
having all freedom necessary. I can change the internal interfaces
without fearing to break someone else's code. There is still lots of
stuff to be done especially after kind of starting from scratch to cope
with embedded systems with low memory resources: After struggling with
some installed C library for quite some time, I decided to implement a
clean environment, including startup code. This is kind of necessary to
avoid dragging in eg. the C I/O stuff which is typically dragged in by
the startup code! The new implementation will also include a complete
new implementation of the STL stuff, amoung other to implement new
optimizations but also to clean up with some legacy resulting from the
changes applied to the STL interface during standardization. Also, I
want to make the headers much more independent of each other to
demonstrate really good compile times: The STL headers include far to
much stuff they don't really need.

Tom

unread,
Oct 17, 2000, 8:44:07 PM10/17/00
to
On 17 Oct 2000 23:13:25 GMT, ku...@ramsen.informatik.uni-konstanz.de
(Dietmar Kuehl) wrote:

>Hi,

Thanks for your candid and interesting response.

Perhaps your implementation may be a good base for an EPOC32 standard
library when they get around to supporting the latest version of gcc.
Mobile phone coders would surely think it was christmas, and perhaps
there's good money in it (the Symbian people are very concerned about
code size and efficiency - see
http://www.octopull.demon.co.uk/epoc/SDK.html)

Tom

Fernando Rodríguez

unread,
Oct 18, 2000, 3:00:00 AM10/18/00
to
On 17 Oct 2000 15:49:02 GMT, ku...@ramsen.informatik.uni-konstanz.de (Dietmar
Kuehl) wrote:

>Hi,


>Josh Sebastian (tar_c...@my-deja.com) wrote:
>: Not exactly. But witness the power of STL:
>
>: #include <algorithm>
>: #include <string>
>: #include <cctype>
>: #include <iostream>
>
>: int main()
>: {
>: std::string s = "Hello, world!";
>: std::transform(s.begin(), s.end(), s.begin(), std::toupper);
>

>The above line should read
>
> std::transform(s.begin(), s.end(), s.begin(),
> static_cast<int(*)(int)>(std::toupper));
>

Would this same technique work on unicode strings (wstring)? O:-)

TIA

//-----------------------------------------------
// Fernando Rodriguez Romero
//
// frr at mindless dot com
//------------------------------------------------

Dietmar Kuehl

unread,
Oct 18, 2000, 3:00:00 AM10/18/00
to
Hi,
Fernando Rodríguez (spa...@must.die) wrote:
: >Josh Sebastian (tar_c...@my-deja.com) wrote:
: >: int main()

: >: {
: >: std::string s = "Hello, world!";
: >: std::transform(s.begin(), s.end(), s.begin(), std::toupper);
: >
: >The above line should read
: >
: > std::transform(s.begin(), s.end(), s.begin(),
: > static_cast<int(*)(int)>(std::toupper));
: >

: Would this same technique work on unicode strings (wstring)? O:-)

Yes. It is written simpler tough:

std::transform(s.begin(), s.end(), s.begin(), std::towupper);

The cast is not needed here because there is only one verson of
'std::towupper' and thus there is no ambiguity. Basically, the same
approach can be extended to arbitrary character types at the cost
of writing a simple template function:

template <typename T>
T to_upper(T c) {
return std::use_facet<std::ctype<T> >(std::locale()).toupper(c);
}

std::transform(s.begin(), s.end(), s.begin(), to_upper<T>);

Of course, it is necessary to implement and install the corresponding
'std::ctype<T>' facets for all types 'T' different than 'char' and
'wchar_t'. ... and the performance of the above code sucks! It is not
that bad with the other approach.

Dim Witt

unread,
Nov 3, 2000, 3:00:00 AM11/3/00
to

"Terje Innerdal" <inn...@dph.no> wrote in message
news:3A02B583...@dph.no...
> I've found out that you can just use the function from stringclass:
> string to_upper(string);


I'm not sure which string class you're talking about but I'm pretty sure
that std::string doesn't have such a function. It's not part of the ISO C++
Standard.

Dim

---
I don't take usenet seriously enough to want to argue about it
I never read e-mails sent in response to usenet posts
You're right, I'm wrong, let's move on
---

Terje Innerdal

unread,
Nov 3, 2000, 7:54:27 AM11/3/00
to
I've found out that you can just use the function from stringclass:
string to_upper(string);

Terje Innerdal

0 new messages