Topic: Howto make string upper, lower
Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/02/01 Raw View
Stefan Gartz <Stefan.Gartz@abc.se> wrote:
>NM> Stefan Gartz <Stefan.Gartz@abc.se> wrote:
>NM> >How do I make a string upper or lower and using locale? >
>
>I have this working (almost right) in MS Visual c++ 5.0 on NT 4
>
>string Upper(const string &s)
>{
> string u = s;
> _USE(locale(), ctype<string::value_type>).toupper(u.begin(), u.end());
> // use_facet<string::value_type>(locale()).toupper(u.begin(),u.end());
> return u;
>}
>void main(void)
>{
> string s1,s2,s3;
>
> s1 = "some swedish letters";
>
> locale::global(locale::locale("Swedish"));
> s2 = Upper(s1); // This is nearly OK one letter is not rised
> // , may be some bug.
>
> setlocale( LC_ALL, "Swedish" );
> s3 = s1+" ";
> char p = (char *)s3.c_str();
> strupr(p); // This is OK all letters is raised.
>}
I don't know what strupr() does. Anyway, the iterators for string
on MSVC++ just happen to be pointers, but the standard doesn't say
they must; so the code above is not portable outside MSVC++, and
perhaps not even from one release to the next of that. The code
below is longer, but portable (modulo bugs).
>NM> std::string
>NM> upcase(
>NM> const std::string& s,
>NM> const std::locale& loc)
>NM> {
>NM> std::string result;
>NM> char* buf = new char[s.size()];
>NM> memcpy(buf,s.data(),s.size());
>NM> try {
>NM> std::use_facet< std::ctype<char> >(loc).
>NM> toupper(buf, buf+s.size());
>NM> result.assign(buf, s.size());
>NM> delete [] buf;
>NM> } catch (...) { delete [] buf; throw; }
>NM> return result;
>NM> }
Anyway, if you only care about Swedish, why bother using standard
locale facilities at all? You can hardwire it to get the result
you want.
Nathan Myers
ncm@nospam.cantrip.org http://www.cantrip.org/
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Stefan.Gartz@abc.se (Stefan Gartz)
Date: 1998/01/27 Raw View
How do I make a string upper or lower and using locale?
string s;
s=3D "=E5=E4=F6" // swedish lower
s.upper() //????
if (s =3D=3D "=C5=C4=D6")=20
;// swedish upper OK
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/01/29 Raw View
Stefan Gartz <Stefan.Gartz@abc.se> wrote:
>How do I make a string upper or lower and using locale?
>
>string s;
>s=3D "=E5=E4=F6" // swedish lower
>s.upper() //????
>if (s =3D=3D "=C5=C4=D6")=20
> ;// swedish upper OK
I don't know what the text above was supposed to say,
but I can guess. There are two answers to your question,
neither as simple as you might like.
The first answer is, write a function:
std::string
upcase(
const std::string& s,
const std::locale& loc)
{
std::string result;
char* buf = new char[s.size()];
memcpy(buf,s.data(),s.size());
try {
std::use_facet< std::ctype<char> >(loc).
toupper(buf, buf+s.size());
result.assign(buf, s.size());
delete [] buf;
} catch (...) { delete [] buf; throw; }
return result;
}
(This involves two allocations; std::string is not my favorite
part of the standard library.) Unfortunately, this only works
for languages in which the upper-case representation is the same
length as the lower-case form. I don't know what would happen
in other languages (e.g. German).
Think about what you're trying to do. Do you really want to
store the up-cased string, or do you want to compare and sort
strings ignoring case?
Consider instead using a locale object as the Compare argument
to a container or algorithm template. Then it's a "simple matter"
to construct a locale to use, with a collate<> facet that ignores
case. Unfortunately I don't know of any systems that provide
standard locale files with this property; so you would need to
roll your own, for now. But then it would be correct, and
portable to any language.
Nathan Myers
ncm@cantrip.org
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Stefan.Gartz@abc.se (Stefan Gartz)
Date: 1998/01/30 Raw View
NM> Stefan Gartz <Stefan.Gartz@abc.se> wrote:
NM> >How do I make a string upper or lower and using locale? >
NM> >string s;
NM> >s=3D "=E5=E4=F6" // swedish lower
NM> >s.upper() //????
NM> >if (s =3D=3D "=C5=C4=D6")=20
NM> > ;// swedish upper OK
NM>
I have this working (almost right) in MS Visual c++ 5.0 on NT 4
string Upper(const string &s)
{
string u = s;
_USE(locale(), ctype<string::value_type>).toupper(u.begin(), u.end());
// _USE is a macro for MS Visual C++ 5.0 for Standard C++ Library:s use_facet
// use_facet<string::value_type>(locale()).toupper(u.begin(),u.end());
return u;
}
void main(void)
{
string s1,s2,s3;
s1 = "some swedish letters";
locale::global(locale::locale("Swedish"));
s2 = Upper(s1); // This is nearly OK one letter is not rised, may be some bug.
setlocale( LC_ALL, "Swedish" );
s3 = s1+" ";
char p = (char *)s3.c_str();
strupr(p); // This is OK all letters is raised.
}
NM> I don't know what the text above was supposed to say, but I can
NM> guess. There are two answers to your question, neither as simple
NM> as you might like.
NM>
NM> The first answer is, write a function:
NM>
NM> std::string
NM> upcase(
NM> const std::string& s,
NM> const std::locale& loc)
NM> {
NM> std::string result;
NM> char* buf = new char[s.size()];
NM> memcpy(buf,s.data(),s.size());
NM> try {
NM> std::use_facet< std::ctype<char> >(loc).
NM> toupper(buf, buf+s.size());
NM> result.assign(buf, s.size());
NM> delete [] buf;
NM> } catch (...) { delete [] buf; throw; }
NM> return result;
NM> }
NM>
NM> (This involves two allocations; std::string is not my favorite
NM> part of the standard library.) Unfortunately, this only works
NM> for languages in which the upper-case representation is the same
NM> length as the lower-case form. I don't know what would happen in
NM> other languages (e.g. German).
NM>
NM> Think about what you're trying to do. Do you really want to
NM> store the up-cased string, or do you want to compare and sort
NM> strings ignoring case?
I want to make the strings letters stored in uppercase.
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]