2013-04-08 67 views
8

Chức năng towlower() dường như không làm việc trong Visual Studio 2012. Dưới đây là một ví dụ:Tại sao hàm towlower() không chuyển đổi Я thành trường hợp thấp hơn?

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

Nhân vật vẫn còn trường hợp trên. Các câu hỏi tương tự đã được hỏi ở đây trước đây nhưng tôi không thể tìm thấy bất kỳ giải pháp nào.

Có phương pháp nào khác mà tôi có thể sử dụng để thay đổi thành chữ thường không?

+0

[Chúng tôi đóng tất cả các câu hỏi typo,] (http://meta.stackexchange.com/questions/167342/close-all-the-typo-questions) bằng cách này. –

+0

@ H2CO3: Bây giờ bạn đã lừa tôi quá: (Xem ['towlower'] (http://en.cppreference.com/w/cpp/string/wide/towlower) – Zeta

+3

Ý của bạn là gì? Không có lỗi chính tả. –

Trả lời

6

Sử dụng phiên bản địa phương nhận biết tolower, nhưng đừng quên cũng đặt ngôn ngữ C.

Ví dụ:

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

in này:

The letter is: Я => я 

dùng miền địa phương trong iostreams là kinh doanh phức tạp, và có hộp một toàn thể Pandora ẩn đằng sau này. Ví dụ: bạn có thể imbue luồng bằng ngôn ngữ và bạn có thể quản lý nhiều miền cùng một lúc và đặc biệt bạn có thể có một miền cho mỗi chuỗi (có thể cần thiết cho chuyển đổi mã hóa chuỗi trạng thái) ... ai đó nên viết sách về điều đó (hoặc thay vì sử dụng Boost.Locale).

0

Nó có gây sát thương ít hơn so với xe kéo không? j/k. Tôi không quen thuộc với R đảo ngược, nhưng tôi biết rằng nếu nhân vật không có một trường hợp tương đương thấp hơn, để (w) thấp hơn sẽ trả về ký tự ban đầu. http://en.cppreference.com/w/c/string/wide/towlower

+1

'Я' có chữ thường -' я' –

5

Tôi thấy hai khả năng. Người đầu tiên là ngôn ngữ không được đặt chính xác. Từ MSDN:

Chuyển đổi trường hợp towlower là ngôn ngữ cụ thể. Chỉ các ký tự liên quan đến miền hiện tại mới được thay đổi trong trường hợp. Các hàm không có hậu tố _l sử dụng ngôn ngữ hiện được đặt.

Cách thứ hai là mã hóa tệp nguồn. L'Я' có thể có nghĩa là những thứ khác nhau dựa trên những gì tệp nguồn của bạn được mã hóa. Nó sẽ không hoạt động, ví dụ, nếu bạn có nó trong UTF-8. Hãy chắc chắn rằng bạn có nó trong UTF-16. Hoặc để loại bỏ bất kỳ sự nhầm lẫn nào có thể đặt nó như thế này '\u042F'

Cập nhật: Trên ý nghĩ thứ hai, toàn bộ doanh nghiệp này là khó khăn. Nếu trình biên dịch hiểu mã hóa một cách chính xác, thông qua BOM ví dụ, nó có thể là tốt với UTF-8 hoặc bất kỳ mã hóa khác. Quan trọng là cần biết mã hóa là gì. Nó phải được thực hiện rất nhiều cụ thể.

cập nhật khác: Để khắc phục vấn đề cố gắng thiết lập miền địa phương thông qua:

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

hoặc sử dụng các phiên bản đó có miền địa phương như tham số (_towlower_l).

Và cũng có trên đầu trang của mọi thứ pragma cho trình biên dịch biết cách xử lý các chuỗi ký tự không phải ASCII trong tệp.

+1

Theo mặc định, tôi tin VC++ xử lý các tệp nguồn dưới dạng mã hóa Windows-1252 (aka-nhưng-not-quite Latin1), có nghĩa là những nhân vật lạ mắt như 'Я' có khả năng bị xáo trộn. Vì vậy, yeah, chắc chắn sử dụng '\ u042f'. :) – jalf

+1

VC++ không nhận dạng Unicode BOM và hoạt động tương ứng, ngay cả trong các tệp UTF-8. – MSalters