2013-04-08 27 views
8

Funkcja towlower() nie wydają się działać w Visual Studio 2012. Oto przykład:Dlaczego funkcja towlower() nie przekształca Я na małą literę я?

#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; 
} 

charakter pozostaje wielkie litery. Podobne pytania zadawano tu wcześniej, ale nie mogę znaleźć żadnych rozwiązań.

Czy istnieje inna metoda zmiany na małe litery?

+0

[Zamykamy wszystkie pytania dotyczące literówek] (http://meta.stackexchange.com/questions/167342/close-all-the-typo-questions) przy okazji. –

+0

@ H2CO3: Teraz też mnie oszukałeś :(Zobacz ['towlower'] (http://en.cppreference.com/w/cpp/string/wide/towlower) – Zeta

+3

Co masz na myśli? Nie ma literówki. –

Odpowiedz

6

Użyj wersji językowej zawierającej tolower, ale nie zapomnij również ustawić ustawień regionalnych C.

Na przykład:

#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; 
} 

Drukuje:

The letter is: Я => я 

Korzystanie lokalizacje w iostreams jest prosta sprawa, a tam pudełko całości Pandory ukryta za to. Na przykład możesz przesyłać strumienie z ustawieniami regionalnymi i możesz zarządzać wieloma lokalizacjami jednocześnie, a w szczególności możesz mieć jeden na wątek (który może być niezbędny do konwersji kodowania ciągów znaków) ... ktoś powinien napisać książkę o tym (lub zamiast tego użyj Boost.Locale).

5

Widzę dwie możliwości. Pierwsza z nich nie jest poprawnie ustawiona. Od MSDN:

Konwersja przypadku towlower jest specyficzna dla ustawień regionalnych. Tylko znaki odnoszące się do aktualnego ustawienia regionalnego zmieniają się w przypadku. Funkcje bez sufiksu _l używają aktualnie ustawionych ustawień narodowych.

Drugim jest kodowanie pliku źródłowego. L'Я' może oznaczać różne rzeczy na podstawie tego, z czym jest zakodowany twój plik źródłowy. Nie zadziała, na przykład, jeśli masz go w UTF-8. Upewnij się, że masz go w UTF-16. Lub w celu usunięcia ewentualnych nieporozumień umieścić go jak ten '\u042F'

Aktualizacja: Na drugim myśli cały ten L biznesu jest trudne. Jeśli kompilator poprawnie zrozumie kodowanie, na przykład poprzez BOM, może to być dobre z UTF-8 lub innym kodowaniem. Ważne, żeby wiedział, co to jest kodowanie. Musi to być bardzo specyficzne dla wdrożenia.

Kolejna zmiana: Aby rozwiązać ten problem, spróbuj ustawić locale poprzez:

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

albo korzystać z wersji, która pobiera jako parametr ustawienia regionalne (_towlower_l).

Jest też na górze wszystko, co pragma, które mówi kompilatorowi, jak traktować w pliku niecyfrowe znaki ASCII.

+1

Domyślnie uważam, że VC++ traktuje pliki źródłowe jako zakodowane Windows-1252 (aka prawie-ale-nie-całkiem Latin1), co oznacza te fantazyjne postacie, takie jak "Я", zostaną prawdopodobnie zniekształcone. Więc tak, zdecydowanie użyj '\ u042f'. :) – jalf

+1

VC++ rozpoznaje BOM Unicode i działa odpowiednio, nawet w plikach UTF-8. – MSalters