मेरे पास एक साधारण प्रोग्राम है जो कमांड लाइन पर पास की गई लोकेशंस की एक श्रृंखला का उपयोग करके wchar_t और char के बीच परिवर्तित करने का परीक्षण करता है। यह उन रूपांतरणों की एक सूची आउटपुट करता है जो लोकेल नाम और स्ट्रिंग को परिवर्तित करने में विफल होने वाली स्ट्रिंग को प्रिंट करके विफल हो जाते हैं।ओएस एक्स पर टूटा हुआ xlocale?
मैं इसे क्लैंग और libC++ का उपयोग कर बना रहा हूं। मेरी समझ यह है कि libC++ का नाम लोकेल समर्थन ओएस एक्स पर 0l30 लाइब्रेरी द्वारा प्रदान किया जाता है।
मुझे कुछ अप्रत्याशित विफलताओं, साथ ही साथ कुछ उदाहरण जहां रूपांतरण विफल होना चाहिए, लेकिन नहीं।
यहां कार्यक्रम है।
#warning call this program like: "locale -a | ./a.out" or pass \
locale names valid for your platform, one per line via standard input
#include <iostream>
#include <codecvt>
#include <locale>
#include <array>
template <class Facet>
class usable_facet : public Facet {
public:
// FIXME: use inheriting constructors when available
// using Facet::Facet;
template <class ...Args>
usable_facet(Args&& ...args) : Facet(std::forward<Args>(args)...) {}
~usable_facet() {}
};
int main() {
std::array<std::wstring,11> args = {L"a",L"é",L"¤",L"€",L"Да",L"Ψ",L"א",L"আ",L"✈",L"가",L""};
std::wstring_convert<usable_facet<std::codecvt_utf8<wchar_t>>> u8cvt; // wchar_t uses UCS-4/UTF-32 on this platform
int convert_failures = 0;
std::string line;
while(std::getline(std::cin,line)) {
if(line.empty())
continue;
using codecvt = usable_facet<std::codecvt_byname<wchar_t,char,std::mbstate_t>>;
std::wstring_convert<codecvt> convert(new codecvt(line));
for(auto const &s : args) {
try {
convert.to_bytes(s);
} catch (std::range_error &e) {
convert_failures++;
std::cout << line << " : " << u8cvt.to_bytes(s) << '\n';
}
}
}
std::cout << std::string(80,'=') << '\n';
std::cout << convert_failures << " wstring_convert to_bytes failures.\n";
}
यहां पर सही उत्पादन
en_US.ISO8859-1 : €
en_US.US-ASCII : ✈
के कुछ उदाहरण हैं यहाँ उत्पादन का एक उदाहरण है कि उम्मीद नहीं है
en_US.ISO8859-15 : €
यूरो चरित्र आईएसओ 8859-15 चारसेट में मौजूद हैं और करता है तो यह असफल नहीं होना चाहिए।
यहाँ है कि मैं उम्मीद लेकिन
en_US.ISO8859-15 : ¤
en_US.US-ASCII : ¤
यह मुद्रा प्रतीक है कि आईएसओ 8859-1 में मौजूद है लेकिन उसे निकाला और आईएसओ 8859-15 में यूरो प्रतीक के साथ बदल दिया गया था है प्राप्त नहीं होता है उत्पादन के उदाहरण हैं। यह रूपांतरण सफल नहीं होना चाहिए, लेकिन कोई त्रुटि संकेत नहीं दी जा रही है। इस मामले की जांच करते समय मुझे लगता है कि दोनों मामलों में '¤' को 0xA4 में परिवर्तित किया जा रहा है, जो '¤' का आईएसओ 885 9 -1 प्रतिनिधित्व है।
मैं सीधे xlocale का उपयोग नहीं कर रहा हूं, केवल अप्रत्यक्ष रूप से libC++ के माध्यम से। मैक ओएस एक्स पर xlocale बस खराब लोकेल परिभाषाओं के साथ टूट गया है? क्या इसे ठीक करने का कोई तरीका है? या क्या मैं कुछ और मुद्दों का परिणाम देख रहा हूं?
किया गया। आईडी 10935025 – bames53
अभी भी 10.8 में टूटा हुआ दिखता है :(हो सकता है कि xlocale डेटा प्राप्त करने और मैन्युअल रूप से एक फिक्स हैक करने का कोई तरीका है? – bames53
यह पता चला है कि यूटीएफ -32 वास्तव में ओएस एक्स पर सभी लोकेशंस द्वारा wchar_t एन्कोडिंग के रूप में उपयोग नहीं किया जाता है , जो काफी दुर्भाग्यपूर्ण है। – bames53