C++ - how to convert string to uppercase/lowercase

J

James Kanze

Why not?
template< typename Char, typename Traits >
std::basic_string< Char, Traits >
toLower(
std::basic_string< Char, Traits > const&
in,
std::locale loc = std::locale() )
{
std::basic_string< Char, Traits >
result( in ) ;
std::use_facet< std::ctype< Char > >( loc )
.toupper( &result[ 0 ], &result[ 0 ] + result.size() ) ;
return result ;
}
Why not use the one-liner (assuming t is an std::string)
std::transform(t.begin(),t.end(),t.begin(),std::bind1st(std::mem_fun(&std::ctype<char>::toupper),&std::use_facet<std::ctype< char > >(std::locale())));

Because I like readable code.
That will work as well as any of the others.

If you're compiler can handle it.
Assuming taking the address of the the return value of
std::use_facet, is not UB. Am I not taking the address of an
r-value in that line?

There might be a problem with using mem_fun with a function that
takes a reference. I haven't tried this particular case, but
I've had problems with it in the past.
Comeau C++ does not complain about it, in any case.

Not all compilers are as good as Comeau.
If that is good, then the following form will aslo work
nicely:
template< typename charT, typename Traits >
std::basic_string< charT, Traits >
toLower(
std::basic_string< charT, Traits > const&
in,
std::locale loc = std::locale() )
{
std::basic_string<charT, Traits> result(in);
std::transform(in.begin(),in.end(),result.begin(),
std::bind1st(std::mem_fun(&std::ctype<charT>::tolower),
&std::use_facet<std::ctype<charT> >(loc)));
return result;
}

Maybe. I can't read it, which means that I won't use it.
 
N

Noah Roberts

Jeff said:
Noah Roberts wrote:

There is no unanimous opinion re. which matters are "trivial." The fact
that you automatically discount the opinions of coworkers who disagree
with your priorities says more about you than it does about them.

When no technical rationale can be expressed it is a trivial matter. If
people then treat others bad because of their opinions, for which they
cannot express reasons, should be fired quite frankly. There is no
excuse at all for treating people bad, much less for something that has
no reasoning behind it.
 
N

Noah Roberts

James said:
I guess the real question, then, is whether you want to work on
projects that succeed or not. All of the shops I've seen where
projects regularly succeeded do impose fairly strict coding
guidelines. And all of those I've seen that didn't typically
had most projects failing.

I don't expect that many successful shops simply impose standards that
have no reasoning behind them. Standards that are not imposed for
real-world, practical, and technical reasons are not good standards.
They're also the least followed.

Furthermore, I don't know many successful shops that allow coworkers to
treat each other badly. An employee that treats others badly for
matters of pure opinion is a problem employee...and someone I wouldn't
want on my team.
So you don't care about the quality of your code, or whether
the project you're working on actually produces something that
works. To each his own.

Non sequiter.
 
J

Joe Smith

James Kanze said:
There might be a problem with using mem_fun with a function that
takes a reference. I haven't tried this particular case, but
I've had problems with it in the past.

I've seen that issue before. This is around my forth attemp at writing such
code, (and the first time I got it to work) and one of my previous times,
ended up with an error due to the template creating a reference to a
reference. I'm not
Not all compilers are as good as Comeau.

MSVC++ also is happy with it, although I've yet to try it under gcc.
If all three are happy with it, then I supsect it is sufficently portable
for most use.
Maybe. I can't read it, which means that I won't use it.

It is not formatted nicely in the email, but if reformated, it is
only slightly harder to read then what you had already posted.

With suffiecnt using directives, and clearer formating, the hardest part
to read is the first few lines, which are virtually identical to those
you posted.

template< typename charT, typename Traits >
basic_string< charT, Traits >
toLower(
basic_string< charT, Traits > const& in,
locale loc = locale() )
{
basic_string<charT, Traits> result(in);

transform(
in.begin(),
in.end(),
result.begin(),
bind1st(
mem_fun(&ctype<charT>::tolower),
&use_facet<ctype<charT> >(loc))
);
return result;
}
 
K

Kai-Uwe Bux

James Kanze wrote:

[snip]

Thanks for the explanation about locales.

[snip]
Still, it's a C-ism:). There isn't a technical reason, but
there is a stylistic one: it communicates the wrong message.
(It says that you're a C hacker who doesn't really understand
C++. I know that this isn't the case in your case, but that's
the way most people will read it.)

Obviously, that's not me sending a message; that's other people indulging in
prejudice when reading :)
That's easy:
int
main()
and grep ^main. That's been the rule in every shop I've worked
in, since my earliest days in C. The name of the function in a
function definition is always in column 1; the name of a
function is never in column 1 otherwise (generally as a result
of other formatting rules).

I think, that does not mix well with indentation from larger structures:

namespace xxx {

int
foo() {
...
}

}

In this case, the function definition starts on column 3. I like
indentation.

What if your employer imposes coding guidelines that ban it:)?
Or your collegues start treating you badly because they don't
like it:)?

Other non-technical reasons. As with any other coding guideline: it's a
cultural thing that should be handled locally. If colleages don't want it,
fine.


Best

Kai-Uwe Bux
 
T

Triple-DES

I'm not sure if it's useful at all to talk about "guaranteed UB",
considering that UB means that nothing is guaranteed.

Yes, I wasn't being 100% clear. What I meant by "guaranteed UB" was
that "the code is guaranteed to have UB". Like this:

int main() {
char * p = "hello";
*p = 0; // this line always results in UB
}

As opposed to "possibly UB":
void f(char * p) {
delete p; // may or may not yield UB
}
 
J

James Kanze

You've apparently met a lot of crappy coders.

Just the opposite. I've worked with real professionals, not
amateur hackers.
The success of software projects I've seen has been directly
proportional to the competence of the developers and
management. Coding guidelines do very little to mitigate
incompetence.

Certainly. But incompetence at the programmer level is fairly
rare. (It seems more common at the management level, although
the situation does seem to be improving.) And a common house
style definitely improves the productivity of competent
programmers.
Admittedly, I have never worked on a code base with strictly
enforced guidelines; rather, the stricter the guidelines, the
less compliant the code seems to become. I personally follow
very strict guidelines re. formatting, and find that most
other successful professionals do the same, but consider
consistency with existing code more important than compliance
to any external document.

So in fact, you do follow guidelines, and recognize their
important. The purpose of an external document isn't just to
have an external document; it's to ensure consistency.
As usual, I agree with your premise, but consider your
conclusion a non sequitur.

And yet, you just admitted the opposite. In the absense of an
"official" guideline, a professional will establish one himself,
probably basing it on existing practice, if there is any. Of
course, if it's just for himself, he may not write it down, but
it will be there anyway, at least in his mind. And competent
management, of course, will act in a manner to ensure that the
programmers under it behave in a professional manner; creating a
written coding guidelines document (rather than just counting on
each programmer doing it themself) contributes to that.
 
J

James Kanze

I don't expect that many successful shops simply impose
standards that have no reasoning behind them.

No shop, start up or not, should impose standards that have no
reasoning behind them. Consistency in style makes code easier
to read and to modify. All successful shops strive for some
consistency in style.
Standards that are not imposed for real-world, practical, and
technical reasons are not good standards. They're also the
least followed.

Coding guidelines are imposed for real-world, practical reasons.
A common, unified style improves programmer productivity. It
makes code reviews easier and more effective, for example (which
also improves software quality).
Furthermore, I don't know many successful shops that allow
coworkers to treat each other badly. An employee that treats
others badly for matters of pure opinion is a problem
employee...and someone I wouldn't want on my team.

Certainly. Not following established guidelines is one form of
treating co-workers badly, and well run shops won't allow it.
 
I

Ian Collins

James said:
No shop, start up or not, should impose standards that have no
reasoning behind them. Consistency in style makes code easier
to read and to modify. All successful shops strive for some
consistency in style.
Collective code ownership is a great way to achieve consistency in style.

Possibly the most important features of coding style guides are brevity
and flexibility. My last team got theirs down to a one pager (on the
team wiki). If the team find a particular style pleasing, it should be
adopted.
Coding guidelines are imposed for real-world, practical reasons.
A common, unified style improves programmer productivity. It
makes code reviews easier and more effective, for example (which
also improves software quality).
It also breaks down those stupid my code/his code barriers.
 
R

Rolf Magnus

James Kanze wrote:

Locales are meant to take care of the "knowing where you come
from". Knowing whether the "MASSE" signifies measurements or
mass, however, requires a bit more intelligence than is present
in most programs. (Most programs probably wouldn't even be able
to handle ASS->aß vs. ISST->isst.)

Well, ASS could also transform to ass (There's a word "Ass").
Basically, it's all a meß ;-)
 
J

James Kanze

Noah Roberts <[email protected]> wrote:

[...]
There is reasoning behind it. Use of "(void)" tells me that
the writer understands neither this basic default guarantee,
nor this basic idiom of the C++ language.

Yes and no. I used to think this too, but I've seen enough of
Kai-Uwe's posts to know that he does understand C++. And
software engineering issues. His opinion counts, just like
yours and mine. From what I've seen, his opinion seems to be a
minority one; that doesn't mean that he doesn't have a right to
it. It does mean that in a large group, seeking consensus for a
common programming style, it's more likely that he'll have to
compromise, but sooner or later, we all have to compromize on
something is a consensus is to be found.

And I can't believe that there's such polemic over a phrase that
I intentionally followed with a smiley. I really don't doubt
that Kai-Uwe (or most of the others participating in this
discussion) would, in a real-life situation, argue his point of
view politely, and accept the consensus decision (which could be
that consistency on this one particular point isn't that
important).
I would, of course, not treat someone bad for doing it, but I
would remind such a person that he is reiterating something
that is already a given, and that the extra verbiage is
inappropriate. (Which is exactly what was done in this case.)

When discussing the guidelines, I would do likewise. If there
were 50 of us, and most felt as strongly as you (and Alf) seem
to about it, then I would say it should be in the guidelines,
and Kai-Uwe should accept that decision. But globally, it's not
something I would present as a make or break issue---if no one
else felt strongly about it, I'd actually tolerate this one
small inconsistency. The important issue, in the end, is that
everyone feels comfortable with the guidelines.
 
J

James Kanze

James Kanze wrote:
[snip]
Still, it's a C-ism:). There isn't a technical reason, but
there is a stylistic one: it communicates the wrong message.
(It says that you're a C hacker who doesn't really
understand C++. I know that this isn't the case in your
case, but that's the way most people will read it.)
Obviously, that's not me sending a message; that's other
people indulging in prejudice when reading :)

Probably:). Still, it takes two to communicate. In this case,
I suspect that the prejudice is at least partially based on the
fact that a lot of ex-C hackers do use the style, and very few
real C++ programmers seem to.
I think, that does not mix well with indentation from larger structures:
namespace xxx {
int
foo() {
...
}
}
In this case, the function definition starts on column 3. I
like indentation.

Yes and no. With regards to grep, there's still no problem:
grep /^ *foo(/. I use vim, however, and vim's definition of the
start of a function is very simplistic: a '{' in column one. So
that's a very strict coding guideline for me.

And I haven't found a good solution for namespaces. On one
hand, namespace scope is namespace scope, regardless of nesting,
and independantly of the editor issues, I don't like the idea of
functions or classes being indented differently according to the
number of nested namespaces which surround them. On the other
hand, it is a bit frustrating that the nesting isn't reflected
in any way in the formatting. So I'm really still
experimenting.

In the one professional project I worked on that made extensive
use of namespaces, the rule was to not indent. That may have
partially been because they overdid the nesting of namespaces
somewhat, so most functions were nested in three or more
namespaces; indenting would have resulted in a lot of excess
indenting.

Another idea which just occured to me (I'll have to give it a
try): We don't "nest" and indent when defining a function which
has class scope; we specify the full class scope in the function
name, e.g.:
void
OuterClass::InnerClass::foo()
{
// ...
}
Maybe that would be the appropriate solution for namespaces too,
e.g.

void
Gabi::project::OuterClass::InnerClass::foo() ...

(Just an idea. Feedback would be appreciated. On obvious
problem would be applying it to anonymous namespaces.)
 
I

Ian Collins

Jeff said:
There are often trade-offs involved. It's not as simple as you make it
sound.


Your coworkers have a vested interest in the quality of your work.

Where did that awful term co-worker originate? I always thought it
indicated the writer couldn't spell colleague. :)

Sorry, couldn't resist in the context of this thread.
 
K

Kai-Uwe Bux

James said:
James Kanze wrote:
[snip]
int main ( void )
This void is a C-ism, best a-voided in C++.
Incorrect: there is no technical reason to avoid "void".
Still, it's a C-ism:). There isn't a technical reason, but
there is a stylistic one: it communicates the wrong message.
(It says that you're a C hacker who doesn't really
understand C++. I know that this isn't the case in your
case, but that's the way most people will read it.)
Obviously, that's not me sending a message; that's other
people indulging in prejudice when reading :)

Probably:). Still, it takes two to communicate. In this case,
I suspect that the prejudice is at least partially based on the
fact that a lot of ex-C hackers do use the style, and very few
real C++ programmers seem to.

I would contend that one usually sees way more of code than just a function
signature. If so, one has way more to go on to form an opinion (in case, an
opinion is needed). There simply is no reason to feel all that strongly
about the issue of "( void )". Bad code usually exhibits many weaknesses
simultaneously.

In any case, I would agree that there can be a plethora of non-technical
reasons to conform to a particular style, and the local consensus (if there
is one) is definitely a _very_ strong reason (so strong that it can even
override technical considerations).

Yes and no. With regards to grep, there's still no problem:
grep /^ *foo(/.

But then, a function call where the return value is discarded

...
foo();
...

would also yield a hit.
I use vim, however, and vim's definition of the
start of a function is very simplistic: a '{' in column one. So
that's a very strict coding guideline for me.

I agree: tools have a strong influence on coding styles. Probably the
strongest influence with cultural issues and local consensus.
And I haven't found a good solution for namespaces. On one
hand, namespace scope is namespace scope, regardless of nesting,
and independantly of the editor issues, I don't like the idea of
functions or classes being indented differently according to the
number of nested namespaces which surround them. On the other
hand, it is a bit frustrating that the nesting isn't reflected
in any way in the formatting. So I'm really still
experimenting.

When namespace nesting gets really deep, the issue becomes more pressing.
In the one professional project I worked on that made extensive
use of namespaces, the rule was to not indent. That may have
partially been because they overdid the nesting of namespaces
somewhat, so most functions were nested in three or more
namespaces; indenting would have resulted in a lot of excess
indenting.

I can see that.
Another idea which just occured to me (I'll have to give it a
try): We don't "nest" and indent when defining a function which
has class scope; we specify the full class scope in the function
name, e.g.:
void
OuterClass::InnerClass::foo()
{
// ...
}
Maybe that would be the appropriate solution for namespaces too,
e.g.

void
Gabi::project::OuterClass::InnerClass::foo() ...

(Just an idea. Feedback would be appreciated. On obvious
problem would be applying it to anonymous namespaces.)

That is interesting. I used to think that a string of qualifications

Gabi::project::OuterClass::InnerClass::...

is a downside (way too verbose). However, it has the advantage of making
very explicit, where the function resides. And, one does not need to
scroll. I guess, that's really a plus. Hm, I need to think.


Best

Kai-Uwe Bux
 
I

Ian Collins

James said:
Yes and no. With regards to grep, there's still no problem:
grep /^ *foo(/. I use vim, however, and vim's definition of the
start of a function is very simplistic: a '{' in column one. So
that's a very strict coding guideline for me.
Using a common editor setup within a team is much better than a written
coding style guide.
And I haven't found a good solution for namespaces. On one
hand, namespace scope is namespace scope, regardless of nesting,
and independantly of the editor issues, I don't like the idea of
functions or classes being indented differently according to the
number of nested namespaces which surround them. On the other
hand, it is a bit frustrating that the nesting isn't reflected
in any way in the formatting. So I'm really still
experimenting.
I've tried using a using directive at the top of source files, which
works if the file contains function definitions for one class.

This does upset some editors, my last team liked Visual Slickedit, which
couldn't tag functions unless they were enclosed in a namespace, or
fully qualified.
In the one professional project I worked on that made extensive
use of namespaces, the rule was to not indent. That may have
partially been because they overdid the nesting of namespaces
somewhat, so most functions were nested in three or more
namespaces; indenting would have resulted in a lot of excess
indenting.
Was the nesting of namespaces a design smell? I find to many nested
namespaces just as bad as too many nested code blocks.
Another idea which just occured to me (I'll have to give it a
try): We don't "nest" and indent when defining a function which
has class scope; we specify the full class scope in the function
name, e.g.:
void
OuterClass::InnerClass::foo()
{
// ...
}
Maybe that would be the appropriate solution for namespaces too,
e.g.

void
Gabi::project::OuterClass::InnerClass::foo() ...

(Just an idea. Feedback would be appreciated. On obvious
problem would be applying it to anonymous namespaces.)
It does work, keeping the verbosity in the name rather than excessive
indentation.
 
N

Noah Roberts

James said:
No shop, start up or not, should impose standards that have no
reasoning behind them. Consistency in style makes code easier
to read and to modify. All successful shops strive for some
consistency in style.

Of course they do. But the difference between f(void) and f() is beyond
trivial. Per the first chapter in C++ Coding Standards, "Don't Sweat
the Small Stuff."

Unless you can come up with some real reason why the difference between
f(void) and f() actually matters, in that it changes intention, edit
step, or causes some sort of confusion...

I'd say there's been plenty of time to express it if you did. The only
argument you offered was, "What if your coworkers start treating you bad
because of it," and I think I answered that quite appropriately.
 
N

Noah Roberts

Daniel said:
So all literature is trivial? Nathaniel Hawthorn, Mark Twain, and Ernest
Hemingway all trivial, simply because there is no "technical rationale"
to explain their greatness?

I stopped here. This is already too stupid to continue reading.

Apples and Oranges. You're being ridiculous.
 
J

James Kanze

Collective code ownership is a great way to achieve
consistency in style.

I'm not sure I understand. The code I write belongs to my
employer. Some employers have very strict coding guidelines,
others don't.
Possibly the most important features of coding style guides
are brevity and flexibility. My last team got theirs down to
a one pager (on the team wiki). If the team find a particular
style pleasing, it should be adopted.
It also breaks down those stupid my code/his code barriers.

It's the company's code.
 
J

James Kanze

Of course they do. But the difference between f(void) and f()
is beyond trivial.

That may be your opinion (and it is mine). But the important
thing is consensus; if most of the programmers in the
organization think it's important, then it's important.
Per the first chapter in C++ Coding Standards, "Don't Sweat
the Small Stuff."
Unless you can come up with some real reason why the
difference between f(void) and f() actually matters, in that
it changes intention, edit step, or causes some sort of
confusion...

The only real reason is that it is what most of the people
working on the project feel. Software development is a
collaborative effort.
I'd say there's been plenty of time to express it if you did.
The only argument you offered was, "What if your coworkers
start treating you bad because of it," and I think I answered
that quite appropriately.

You mean by ignoring it.

I work with people, and their opinions matter.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,059
Latest member
cryptoseoagencies

Latest Threads

Top