2012-09-11 22 views
6

Tôi đang sử dụng cài đặt ngôn ngữ của Nga trên PC của mình.
Nếu tôi sẽ thiết lập:Liệu std :: locale :: toàn cầu có ảnh hưởng đến hàm printf() không?

class numpunct_withpoint: public numpunct<char> 
{ 
protected: 
    /// Override the function that gives the decimal separator. 
    char do_decimal_point() const 
    { 
     return '.'; 
    } 
}; 
... 
locale loc(std::locale::classic(), new numpunct_withpoint); 
std::locale::global(loc); 


và hơn

printf("%f", 3.14); 

Output là:

3,14 

tách số thập phân là "" không thích chức năng do_decimal_point ! Làm cách nào để thay đổi cài đặt ngôn ngữ C cho dấu tách thập phân với ngôn ngữ C++?


Cảm ơn bạn đã trả lời!
Nhưng, chức năng C setlocale có ảnh hưởng đến đối tượng cout C++ không?

setlocale(LC_NUMERIC, "C"); 

Điều này có ảnh hưởng gì khi in giá trị thập phân qua cout?

Trả lời

0

Thư viện C không sử dụng cùng một cài đặt miền địa phương như C++. Để ghi đè miền địa phương được sử dụng bởi printf, sử dụng setlocale:

setlocale(LC_NUMERIC, "POSIX"); 

hoặc tương đương.

+0

Tuy nhiên, 'locale :: chức năng global' * sẽ * gọi' setlocale' cho bạn, nếu bạn vượt qua nó một miền địa phương đặt tên . –

5

Khi bạn đặt ngôn ngữ C++ toàn cục, ngôn ngữ C cũng được sửa đổi. Nếu bạn sửa đổi ngôn ngữ C, ngôn ngữ C++ toàn cục không phải là được sửa đổi.

Phần sau minh họa cài đặt ngôn ngữ chung C++.

#include <cstdio> 
#include <clocale> 
#include <fstream> 

int main() { 
    const char * locale_name = "French_France.1252"; // or "fr_Fr.UTF-8" on Unix 
    double value = 1.2; 

    std::locale::global(std::locale(locale_name)); 

    std::ofstream("out.txt") << "C++ " << value << '\n'; 

    if (FILE *f = std::fopen("out.txt", "a")) { 
     std::fprintf(f, "C %1.1e\n", value); 
     std::fclose(f); 
    } 
} 

Cả đầu ra C và C++ phải sử dụng dấu phẩy thập phân.

C++ 1,2
C 1,2e + 000

Nếu bạn thay thế thiết lập cáC++ locale C với thiết lập locale C, std::setlocale(LC_ALL, locale_name);, sau đó đầu ra nên thay đổi để chỉ những đầu ra C sử dụng dấu phẩy thập phân trong khi đầu ra C++ vẫn sử dụng ký hiệu thập phân thời gian mặc định.

C++ 1.2
C 1,2e + 000

Tuy nhiên, thực tế là thiết lập cáC++ locale C ảnh hưởng đến locale C không làm cho C miền địa phương mở rộng theo cách mà C++ miền địa phương đang có. Các khía cạnh tùy chỉnh C++ sẽ không bao giờ được sử dụng bởi các hàm dựa trên ngôn ngữ C. Thay vào đó, bạn phải dựa vào hệ thống của mình hỗ trợ một số miền địa phương có tên có chức năng bạn cần.

Cụ thể, std::locale::global() được xác định để đặt ngôn ngữ C bằng cách sử dụng tên của ngôn ngữ C++ mà bạn chọn, nếu nó có tên. Hành vi được thực hiện được xác định nếu ngôn ngữ C++ không có tên.Ngoài ra, C++ xác định rằng việc kết hợp hai tên miền được đặt tên sẽ tạo ra một miền địa phương có tên. Một số triển khai sản xuất tên kết hợp hữu ích cho phép bạn kết hợp loại locale C chỉ bằng cách thiết lập C++ ngôn ngữ:

std::locale::global(std::locale(std::locale("ru_RU"), "C", std::locale::numeric)); 

Với libstdC++ này tạo ra một miền địa phương tên là:

LC_CTYPE = ru_ru; LC_NUMERIC = C; LC_TIME = ru_RU; LC_COLLATE = ru_RU; LC_MONETARY = ru_RU; LC_MESSAGES = ru_RU; LC_PAPER = ru_RU; LC_NAME = ru_RU; LC_ADDRESS = ru_RU; LC_TELEPHONE = ru_RU; LC_MEASUREMENT = ru_RU; LC_IDENTIFICATION = ru_RU LC_CTYPE = ru_RU; LC_NUMERIC = C; LC_TIME = ru_RU ; LC_COLLATE = ru_RU; LC_MONETARY = ru_RU; LC_MESSAGES = ru_RU; LC_PAPER = ru_RU; LC_NAME = ru_RU; LC_ADDRESS = ru_RU; LC_TELEPHONE = ru_RU; LC_MEASUREMENT = ru_RU; LC_IDENTIFICATION = r u_RU

Để vị trí C được đặt thành cùng một hỗn hợp giữa miền địa phương "ru_RU" và "C" làm ngôn ngữ C++.

Thật không may, các triển khai khác chọn ít hoạt động hữu ích hơn, mặc dù vẫn tuân thủ về mặt kỹ thuật. Trong Visual Studio

std::locale::global(std::locale(std::locale("Russian_Russia.1251"), "C", std::locale::numeric)); 

tạo ngôn ngữ có tên "C". Vì vậy, trong khi miền địa phương C++ là hỗn hợp thích hợp của các loại miền địa phương của Nga và C, thì ngôn ngữ C được đặt đơn giản là "C". Vì vậy, trên những nền tảng để trộn loại locale C bạn phải trực tiếp đặt C ngôn ngữ:

// set the C++ locale first 
std::locale::global(std::locale(std::locale("Russian_Russia.1251"), "C", std::locale::numeric)); 

// set the C locale second, because it will not overwrite the changes you made to the C++ locale 
std::setlocale(LC_ALL, "Russian_Russia.1251"); 
std::setlocale(LC_NUMERIC, "C");