std::locale wirt exception
-
SeppJ schrieb:
Hacker schrieb:
Michael E. schrieb:
Die Lösung wurde doch schon genannt: Benutze den compilerspezifischen String.
Danke
! Aber wo wurde die denn genannt? Im anderen Link?Also compilerspezifisch ist nicht ganz richtig, eher plattformspezifisch. Plattformunabhängig sind nur die locales "C" (im Prinzip US-Englisch) und ....
Naja, jedenfalls funktioniert das "Programm" mit der system-lokale auch nicht - und wenn man dann (deiner Argumentation folgend) keine anderen nehmen sollte, hat man ja keine Wahl, als toupper, bzw. tolower selbst zu implementieren.
-
So so! es funktioniert also nicht. Lies dir doch bitte mal den ersten Link in meiner Signatur gründlich durch und stell dann noch einmal eine brauchbare Frage.
(Dass ich das mal bei jemandem mit 1500 Beiträgen schreiben muss
)P.S.: Du sagst also, dass
http://ideone.com/jbkvZ
bei dir eine Exception wirft?
-
SeppJ schrieb:
So so! es funktioniert also nicht. Lies dir doch bitte mal den ersten Link in meiner Signatur gründlich durch und stell dann noch einmal eine brauchbare Frage.
(Dass ich das mal bei jemandem mit 1500 Beiträgen schreiben muss
)Ok.
Nein, es funktioniert nicht, da es einfach Umlaute ignoriert (was Michael E. furchtbar blöd findet - und ich auch). Das sollte es aber nicht, wenn das globale locale auf German gesetzt wurde. Also?

-
Hacker schrieb:
Nein, es funktioniert nicht, da es einfach Umlaute ignoriert (was Michael E. furchtbar blöd findet - und ich auch). Das sollte es aber nicht, wenn das globale locale auf German gesetzt wurde. Also?

So so! "Es" "ignoriert" Umlaute. Dann ist ja jetzt alles klar.
-
SeppJ schrieb:
Hacker schrieb:
Nein, es funktioniert nicht, da es einfach Umlaute ignoriert (was Michael E. furchtbar blöd findet - und ich auch). Das sollte es aber nicht, wenn das globale locale auf German gesetzt wurde. Also?

So so! "Es" "ignoriert" Umlaute. Dann ist ja jetzt alles klar.
Kennst du den anderen Thread nicht?
#include <iostream> #include <string> void firstToupperOtherTolower(std::string& str) { if(str.length()) str.at(0) = toupper(str.at(0)); for(std::string::size_type a(1);a < str.length();++a) str.at(a) = tolower(str.at(a)); } int main() { std::locale::global(std::locale("")); std::string vorname, nachname; std::cout << "Bitte Vornamen eingeben: "; std::getline(std::cin, vorname);///PI zuliebe std::cout << "Bitte Nachnamen eingeben: "; std::getline(std::cin, nachname); firstToupperOtherTolower(nachname); firstToupperOtherTolower(vorname); std::cout << "Ihr Name ist " << vorname << ' ' << nachname << '\n'; }Eingabe: oNI oNI Ausgabe: Oni Oni
Eingabe: öLÄ öNÜ Ausgabe: ölÄ önÜ
-
http://www.cplusplus.com/reference/std/locale/ctype/tolower/
http://fara.cs.uni-potsdam.de/~kaufmann/?page=GenCppFaqs&faq=stricmp#Answ
-
Michael E. schrieb:
http://www.cplusplus.com/reference/std/locale/ctype/tolower/
http://fara.cs.uni-potsdam.de/~kaufmann/?page=GenCppFaqs&faq=stricmp#AnswErstes Kenn ich (natürlich) schon, zweites hat mit meine
r Fragem Problem nichts zu tun (strings case-insensitive vergleichen!?)
-
Hacker schrieb:
std::getline(std::cin, vorname);///PI zuliebewat
-
314159265358979 schrieb:
Hacker schrieb:
std::getline(std::cin, vorname);///PI zuliebewat
Hattest dich doch letztens mit Werner Salomon gezofft?

-
ney.
-
Hacker schrieb:
Erstes Kenn ich (natürlich) schon,
Warum benutzt du es dann nicht?
zweites hat mit meine
r Fragem Problem nichts zu tun (strings case-insensitive vergleichen!?)
Es würde helfen, wenn du dir das mal durchliest, statt schon vorher zu sagen, dass das nichts mit dem Thema zu tun haben soll. Tipp: Wie könnte man wohl Strings case-insensitiv vergleichen?
-
Tja, bin eben zu schnell. Aber auch so:
Michael E. schrieb:
Wie könnte man wohl Strings case-insensitiv vergleichen?
Die std::transform Methode ist laut (dem bisher sehr zuverlässigem C++-reference) äquivalent zu:
template < class InputIterator, class OutputIterator, class UnaryOperator > OutputIterator transform ( InputIterator first1, InputIterator last1, OutputIterator result, UnaryOperator op ) { while (first1 != last1) *result++ = op(*first1++); // or: *result++=binary_op(*first1++,*first2++); return result; }Was resultiert zu mit Input & OutputIterator = std::basic_string<char>::iterator, UnaryOperator = tolower/toupper:
OutputIterator transform ( std::string::iterator first1, std::string::iterator last1,std::string::iterator result, int(*)(int) op ) { while (first1 != last1) *result++ = tolower(*first1++); return result; }WAs im Endeffekt wieder nur das macht, was die anderen "Versuche" auch fabrizieren. Ohne den globalen locale vorher zu verändern wird sich hier auch nichts verändern.
-
EDIT: Ha! Wirft eine Exception. Ha SepJ!

-
void firstToupperOtherTolower(std::string& str) { if(str.length()) str.at(0) = std::toupper(str.at(0)); for(std::string::size_type a(1);a < str.length();++a) std::transform<std::string::iterator, std::string::iterator, int(*)(int)>(str.begin(), str.end(), str.begin(), std::tolower); }1. "Capitalize" wäre ein passenderer Name.
2. Wieso checkst du zuerst die Stringlänge und verwendest dann at, das nochmal checkt?
3. Wieso gibst du bei transform explizit der Template-Parameterliste an?
-
SeppJ schrieb:
Wobei ich noch nie den Grund verstanden habe, wieso man etwas anderes nehmen sollte als "" (oder "C"), denn ich will nicht, dass ein Programm plötzlich eine ungewöhnte Locale benutzt, bloß weil es von einem Deutschen programmiert wurde. Da ist doch der ganze Sinn von Loacales futsch, wenn das Programm nicht die Systemlocale (und damit meine Sprache) benutzt (oder wenn es sein muss die Standardlocale), sondern die Sprache des Programmierers.
Na es könnte sein dass man dem
ProgrammiererUser eine Option anbieten möchte die Sprache/Locale selbst auszuwählen, unabhängig von der im OS eingestellten Sprache.Denk an Embedded Systems. Kann schnell passieren dass man während das Programm läuft die Sprache/Locale umschalten möchte.
-
Ethon schrieb:
void firstToupperOtherTolower(std::string& str) { if(str.length()) str.at(0) = std::toupper(str.at(0)); for(std::string::size_type a(1);a < str.length();++a) std::transform<std::string::iterator, std::string::iterator, int(*)(int)>(str.begin(), str.end(), str.begin(), std::tolower); }1. "Capitalize" wäre ein passenderer Name.
2. Wieso checkst du zuerst die Stringlänge und verwendest dann at, das nochmal checkt?
3. Wieso gibst du bei transform explizit der Template-Parameterliste an?Deine Fragen sind total berechtigt, also
1. Ja, hast Recht.
2. Damit keine Exception geworfen wird. (Oder soll sie das dann gerade? Wäre dann aber nicht erkennbar, was genau das Problem ist (für den Anwender der Funktion). Also lieber doch so)
3. Komischerweise gibt das bei mir folgende Fehler:GCC 4.6.2 schrieb:
No matching function to call for ... BLABLABLA
-
std::transform() N mal über den ganzen String drüberzulassen (N = Länge des Strings) macht auch so überhaupt keinen Sinn.
if (str.size() > 0) { str[0] = std::toupper(str[0]); std::transform(str.begin() + 1, str.end(), str.begin() + 1, std::tolower); }
-
2. Damit keine Exception geworfen wird. (Oder soll sie das dann gerade? Wäre dann aber nicht erkennbar, was genau das Problem ist (für den Anwender der Funktion). Also lieber doch so)
Mal zum Vergleich wie at und der Operator definiert sein können:
char& at(size_t i) { if(i >= len) throw out_of_range(); return data[i]; } char& operator[](size_t i) { return data[i]; }Klingelts?

at benutzt du gerade, wenn du möchtest dass der String die Länge selbst checkt, der Operator macht das nicht.3. Komischerweise gibt das bei mir folgende Fehler:
Ja, seltsame Sache. Komischerweise hilft es, tolower anstatt std::tolower zu schreiben. Wieso? Keine Ahnung ...
Warscheinlich gibt es irgendwo in locale eine überladene Version von tolower, du willst aber explizit die C-Version.
-
hustbaer schrieb:
std::transform() N mal über den ganzen String drüberzulassen (N = Länge des Strings) macht auch so überhaupt keinen Sinn.
if (str.size() > 0) { str[0] = std::toupper(str[0]); std::transform(str.begin() + 1, str.end(), str.begin() + 1, std::tolower); }Ah, Nein! Da hab ich im Code einfach Cut & Paste gemacht, ohne auf die Schleife zu achten

-
Ethon schrieb:
Warscheinlich gibt es irgendwo in locale eine überladene Version von tolower, du willst aber explizit die C-Version.
Ah, stop. Die zweite erwartet auch eine locale-Instanz? Klar, dass du da Recht hast, hab ich so auf C++-Reference ARAIR nicht gesehen..(Edit: Obwohl es natürlich so da steht).