2013-04-08 12 views
8

Die Funktion towlower() scheint nicht 2012 in Visual Studio zu arbeiten:Warum konvertiert die Funktion towlower() das Я nicht in einen Kleinbuchstaben я? Hier ist ein Beispiel

#include <string> 
#include <iostream> 
#include <io.h> 
#include <fcntl.h> 
#include <wctype.h> 

using namespace std; 

int main() 
{ 
    _setmode(_fileno(stdout), _O_U8TEXT); 
    wcout << (wchar_t)towlower(L'Я') << endl; 
    system("pause"); 
    return 0; 
} 

Der Charakter bleibt Großbuchstaben. Ähnliche Fragen wurden schon früher gestellt, aber ich kann keine Lösungen finden.

Gibt es eine andere Methode, die ich verwenden kann, um in Kleinbuchstaben zu wechseln?

+0

[Wir schließen alle Tippfehler Fragen,] (http://meta.stackexchange.com/questions/167342/close-all-the-typo-questions) übrigens. –

+0

@ H2CO3: Jetzt hast du mich auch ausgetrickst :(. Siehe ['towlower'] (http://en.cppreference.com/w/cpp/string/wide/towlower) – Zeta

+3

Was meinst du? Es gibt keinen Tippfehler. –

Antwort

6

Verwenden Sie die länderspezifische Version von tolower, aber vergessen Sie nicht, auch das Gebietsschema C festzulegen.

Zum Beispiel:

#include <clocale> 
#include <locale> 
#include <iostream> 

int main() 
{ 
    std::setlocale(LC_CTYPE, ""); 
    std::wcout << L"The letter is: " << L'Я' << L" => " 
       << std::tolower(L'Я', std::locale("")) << std::endl; 
} 

Diese Drucke:

The letter is: Я => я 

Mit Paradiesen iostreams ist heikle Angelegenheit, und es gibt eine ganze Büchse der Pandora dahinter verbirgt. Beispielsweise können Sie Ströme mit einem Gebietsschema imbue geben, und Sie können mehrere Gebietsschemas auf einmal verwalten, und insbesondere können Sie einen pro Thread haben (der für statusbehaftete Zeichencodierungskonvertierungen erforderlich sein kann) ... sollte jemand ein Buch schreiben darüber (oder stattdessen Boost.Locale verwenden).

5

Ich sehe zwei Möglichkeiten. Das erste ist, dass das Gebietsschema nicht korrekt eingestellt ist. Von MSDN:

:

Die Konvertierung von towlower ist länderspezifisch. Nur die Zeichen, die für das aktuelle Gebietsschema relevant sind, werden im Fall geändert. Die Funktionen ohne das Suffix _l verwenden das aktuell eingestellte Gebietsschema.

Die zweite ist die Codierung der Quelldatei. L'Я' könnte verschiedene Dinge bedeuten, basierend auf dem, mit dem Ihre Quelldatei kodiert ist. Es wird nicht funktionieren, zum Beispiel, wenn Sie es in UTF-8 haben. Stellen Sie sicher, dass Sie es in UTF-16 haben. Oder jede mögliche Verwirrung zu entfernen formulierte es so '\u042F'

Update: Am zweiten Gedanken dieses ganze L Geschäft heikel ist. Wenn der Compiler die Codierung korrekt versteht, z. B. über BOM, kann dies mit UTF-8 oder einer anderen Kodierung in Ordnung sein. Wichtig, dass es wissen sollte, was die Codierung ist. Es muss sehr umsetzungsspezifisch sein.

Ein weiteres Update: das Problem zu beheben versuchen Locale zu setzen über:

_wsetlocale(LC_ALL, L"ru-RU"); 

oder die Version verwenden, die das Gebietsschema als Parameter übernimmt (_towlower_l).

Und es gibt auch zuallererst eine pragma, die dem Compiler mitteilt, wie man Nicht-ASCII-String-Literale in der Datei behandelt.

+1

Standardmäßig glaube ich, VC++ behandelt Quelldateien als Windows-1252 codiert (aka fast aber nicht ganz Latin1), was bedeutet dass ausgefallene Charaktere wie "Я" wahrscheinlich verstümmelt werden. Also ja, verwende definitiv '\ u042f'. :) – jalf

+1

VC++ erkennt die Unicode-Stückliste und verhält sich entsprechend, auch in UTF-8-Dateien. – MSalters