Was sagt der C++ Standard zu toupper
-
Habe folgendes Testprogramm geschrieben:
#include <vector> #include <string> #include <cstring> #include <iostream> using namespace std; bool up_case_comp(const string& s1,const string& s2) { string i1 = s1; transform(i1.begin(),i1.end(),i1.begin(), _toupper); string i2 = s2; transform(i2.begin(),i2.end(),i2.begin(), _toupper); return i1.compare(i2) < 0; } int main() { vector<string> theList; theList.push_back("alice"); theList.push_back("Hello"); theList.push_back("below"); theList.push_back("hello"); sort(theList.begin(), theList.end(), up_case_comp); vector<string>::const_iterator it; for(it = theList.begin(); it != theList.end(); it++) cout << *it << endl; return 0; }Output schrieb:
alice
below
Hello
hellowenn ich mit g++ 3.3.5 kompiliere. Soweit so gut.
Kompiliere ich den gleichen Code aber mit MSVC 6.0 erscheint der Output unsortiert. Hmm.
Jetz habe ich in meiner up_case_comp() _toupper mit toupper ersetzt.
Juhuu Output ist sortiert. wahrscheinlich ist _toupper nicht Standardkonform.
Jetzt mache ich den Quercheck und compiliere die Version mit toupper mit g++. Das kompiliert nicht mal. Scheinbar gibt es in den headern von g++ gar keine funktion toupper die zu transform kompatibel ist.wenn ich eine funktion
int mytoupper( const int & c ) { return toupper(c); }verwende dann funktioniert es wieder.
Bin ich über ein nicht Standardkonformität bei beiden g++ und MSCV6.0 gestolpert ?
Kurt
-
toupper ist standardkonform, _toupper nicht.
-
waren nicht alle Bezeichner mit _ oder __ Compilerabhänig ?
-
SeppSchrot schrieb:
toupper ist standardkonform, _toupper nicht.
Heisst das jetzt g++ ist der Böse, oder könnte es ein vom Standard nicht geregeltes Implementationsdetail sein dass toupper nicht mit transform kompatibel ist ?
Kurt
-
beim g++ bis 3.4 gab es bei toupper irgend ein Problem. Ich glaub das war als Macro implementiert oder so etwas. Naja, nimm einfach g++ 3.4 oder 4.0

-
kingruedi schrieb:
beim g++ bis 3.4 gab es bei toupper irgend ein Problem. Ich glaub das war als Macro implementiert oder so etwas. Naja, nimm einfach g++ 3.4 oder 4.0

Danke. Jetzt habe ich endlich einen Grund auf 3.4 umzusteigen.
Kurt
-
Scheinbar gibt es in den headern von g++ gar keine funktion toupper die zu transform kompatibel ist.
Da irst du dich. transform erwartet keinen festen Typ. Der letzte Parameter ist ein Template-Parameter und wird beim Aufruf passend hergeleitet. Und hier genau ist jetzt das Problem. Im Namespace std gibt es mehr als eine toupper-Funktion. Aus diesem Grund ist:
transform(i1.begin(),i1.end(),i1.begin(), toupper);schlicht mehrdeutig und damit kein gültiges C++.
Die logische Alternative:
transform(i1.begin(),i1.end(),i1.begin(), static_cast<int (*)(int)>(toupper));wiederum ist nicht portabel, da der C++ Standard keine festen Signaturen vorschreibt.
Die standkonforme und portable Lösung ist die Variante mit mytoupper. Wenn du jetzt noch das char <-> unsigned char <-> int Problem (das ich hier jede Woche mindestens einmal erkläre) berücksichtigst, dann wird's am Ende sogar korrekt.
-
Wenn du es jede Woche min. einmal erklärst, wieso tust du es nicht dann in dein C++ FAQ auf deiner Seite? (Auch wenn ich garnicht weiß, worum es bei dem Problem geht ;))
-
gute frage

-
Brutus schrieb:
Wenn du es jede Woche min. einmal erklärst, wieso tust du es nicht dann in dein C++ FAQ auf deiner Seite? (Auch wenn ich garnicht weiß, worum es bei dem Problem geht ;))
Weil mir schlicht kein guter Titel einfällt. Ein Titel wie "Was muss man bei der Benutzung von Character-Classification und -Conversion-Funktionen wie z.B. tolower beachten?" hört sich für den vorbeistreifenden Leser imo etwa so an: Bla Bla Bla, Langweilig, Bla Bla?
-
Schreib am Anfang
#include <cctype>dazu. Dann gibts auch toupper.
-
HumeSikkins schrieb:
Brutus schrieb:
Wenn du es jede Woche min. einmal erklärst, wieso tust du es nicht dann in dein C++ FAQ auf deiner Seite? (Auch wenn ich garnicht weiß, worum es bei dem Problem geht ;))
Weil mir schlicht kein guter Titel einfällt. ...
Wie wär's den mit
HumeSikkins schrieb:
...das char <-> unsigned char <-> int Problem...
?

evtl. noch "... und toupper/tolower" dahinter ...Gruß,
Simon2.