Wie funktioniert tolower?
-
lucky_tux schrieb:
Hallo zusammen,
wie aber verwendet man tolower oder toupper möglichst unkompliziert auf einer ganzen Zeichenkette? Bis jetzt verwende ich immer folgende Variante. Beispiel:
#include <iostream> #include <string> #include <algorithm> #include <ctype.h> using namespace std; int f_tolower(int x) { return tolower(x); } int main() { string s = "KeIN langWEILIGER StAnDarDSPRUCH!"; transform(s.begin(), s.end(), s.begin(), &f_tolower); /* transform(s.begin(), s.end(), s.begin(), &tolower) * funktioniert leider nicht */ cout << s << endl; }
Geht das auch noch einfacher? Gibt es eine derartige Funktion oder gar ein Funktionsobjekt?
Grüße Martin
Also eigentlich finde ich das schon ziemlich optimal: Sagt Genau und minimal das aus, was man tut: "Transformiere aus einem string (von begin bis end) in einen anderen mit tolower" .....
Kürzer und sprechender geht's IMO nicht - höchstens, indem man sich auf komplette strings bezieht, könnte man noch einen Parameter loswerden.Unschön finde ich aber auch, dass tolower eine int-Signatur hat ... Besseres fällt mir da im Augenblick auch nicht ein (wundert mich, dass man einen anderen Namen verwenden muss und kein normaler Overload funktikoniert, weiß aber auch nicht, warum).
Gruß,
Simon2.
-
Schreibe ich
transform(s.begin(), s.end(), s.begin(), &tolower);
so lässt sich das Beispiel nicht kompilieren:
# g++ main.cpp
main.cpp:10: error: no matching function for call to 'transform(__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, <unresolved overloaded function type>)'Ich gehe davon aus, dass Präprozessordirektiven verwendet wurden. Leider habe ich momentan nicht die Möglichkeit das nachzuprüfen. Vlt. wagt ja jemand einen Blick in ctype? ...
Grüße Martin
--
Anmerkung: Da waren Andere schneller... Hab mir wohl ein wenig Zeit beim Tippen gelassen
-
Jetzt brat mir n Storch und die Beine recht knusprig...
Kann das Problem (welches ich definitiv auch schon hatte in genau dieser Form) gerade weder mit nem 3.2er noch mit nem 4.1er g++ nachstellen.
-
Hi,
also ich habe keine Probleme, das nachzustellen (g++ (GCC) 3.4.4 (cygming special) (gdc 0.12, using dmd 0.125)).
In der ctype finde ich:
int __cdecl tolower(int);Im Standard steht
ISO/IEC 14882: 2003 (Secon Edition); Kap. 22.1.3.2.2 schrieb:
template <class charT> charT tolower(charT c, const locale& loc);
Returns:use_facet<ctype<charT> >(loc).tolower(c)
.Gruß,
Simon2.
-
Hallo,
$ g++-2.95 --version
2.95.4$ g++-2.95 main.cpp
$ g++-4.1 --version
g++-4.1 (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.$ g++-4.1 main.cpp
main.cpp: In function 'int main()':
main.cpp:10: error: no matching function for call to 'transform(__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, <unresolved overloaded function type>)'Mit einem alten Compiler und einer älteren libstdc++ funktioniert alles wunderbar. Meinermeinung nach sollte man jedoch nicht darauf vertrauen, dass die "richtige" Version verwendet wird, sondern möglichst kompatiblen Code schreiben, auch wenn dieser ein wenig komplexer und/oder einen größeren Umfang besitzt.
Grüße Martin
-
LordJaxom schrieb:
CStoll schrieb:
Was genau funktioniert denn an transform(...,tolower); nicht?
Ich nehme an (und luck_tux' Nickname bestätigt mich irgendwo dabei), dass er unter Linux arbeitet. Hier sind tolower und toupper irgendwelche Makros o.ä.. Jedenfalls nichts was der g++ in diversen Versionen (ich glaube bis hin zur aktuellen) als Funktionspointer erkennen würde.
Ich habs unter Linux bisher auch immer wie oben machen müssen. (Allerdings war mein my_tolower immer inline
)
Ich denke ihr beobachtet hier ein anderes Problem: tolower ist, in abhängigkeit der inkludiereten Header, ein überladener Name, was einen Aufruf von transform(..., &tolower) ungültig macht. Ein Cast schafft abhilfe: transform(..., static_cast<int(*)(int)>(tolower)). Korrekt ist das Ergebnis aber nicht, zumindest, wenn char != unsigned char ist. Wie ich hier schon ca. 1 Millionen mal geschrieben habe, muss man bei char != unsigned char die Zeichen erst nach unsigned char casten, bevor man sie an tolower übergibt.
Sinnvoll wäre also:
inline int myTolower(int c) { return std::tolower(static_cast<unsigned char>(c)); } ... transform(..., myTolower);
-
Äh ich hätt da noch eine Frage zum Thema, wie kann ich die Buchstabenlänge in einem string rausbekommen? Gibts da irgend eine Funktion? Also ich kenne "strlen", aber das geht ja nur bei char oder?
Ähm und was ist der Unterschied zwischen "ctype.h" und "cctype"?
Dankeschön schon mal im Voraus.
-
Stromberg schrieb:
Äh ich hätt da noch eine Frage zum Thema, wie kann ich die Buchstabenlänge in einem string rausbekommen? Gibts da irgend eine Funktion? Also ich kenne "strlen", aber das geht ja nur bei char oder?
Da gibt's sogar zwei - size() und length().
Ähm und was ist der Unterschied zwischen "ctype.h" und "cctype"?
Dankeschön schon mal im Voraus.<ctype.h> gehört zu C, <cctype> ist die C++ Entsprechung dazu (und definiert alle Funktionen im Namensraum 'std::').
-
CStoll schrieb:
Stromberg schrieb:
Äh ich hätt da noch eine Frage zum Thema, wie kann ich die Buchstabenlänge in einem string rausbekommen? Gibts da irgend eine Funktion? Also ich kenne "strlen", aber das geht ja nur bei char oder?
Da gibt's sogar zwei - size() und length().
hat das einen grund?
sind die wirklich identisch?
-
Ja, ist historisch so entstanden (length() in Anlehnung an die String"länge", size() zur Verwendbarkeit als STL-Container). Und ja, die Methoden sind identisch.