Domanda

In un progetto tutte le stringhe interne sono tenuti in utf-8 codifica. Il progetto è portato su Linux e Windows. V'è la necessità di una funzionalità to_lower ora.

In POSIX OS potrei usare std :: ctype_byname ( "ru_RU.UTF-8"). Ma con g ++ (Debian 4.3.4-1), ctype :: tolower () non riconosce i caratteri UTF-8 russi (testo latino è caratteri minuscoli bene).

In Windows, libreria standard di mingw tiri eccezione "std :: runtime_error: Locale :: :: sfaccettatura _ nome S_create_c_locale non valida". Quando provo a costruire std :: ctype_byname con "ru_RU.UTF-8" argomento

Come faccio a implementare / trovare std :: ctype per UTF-8 su Windows? Il progetto dipende già in libiconv (codecvt sfaccettatura si basa su di esso), ma non vedo un modo ovvio per implementare to_lower con esso.

È stato utile?

Soluzione

Se tutto ciò che serve è to_lower per i caratteri cirillici è possibile scrivere una funzione da soli.

АБВГДЕЖ in UTF8  D0 90 D0 91 D0 92 D0 93 D0 94 D0 95 D0 96 0A
абвгдеж in UTF8  D0 B0 D0 B1 D0 B2 D0 B3 D0 B4 D0 B5 D0 B6 0A

Ma non dimenticate che è UTF8 codifica multibyte.

Inoltre è possibile provare a convertire una stringa da UTF8 a wchar_t (utilizzando libiconv) e utilizzare la funzione specifica di Windows per implementare to_lower.

Altri suggerimenti

Prova ad utilizzare STLport

  Here is a description of how you can use STLport to read/write utf8 files.
utf8 is a way of encoding wide characters. As so, management of encoding in
the C++ Standard library is handle by the codecvt locale facet which is part
of the ctype category. However utf8 only describe how encoding must be
performed, it cannot be used to classify characters so it is not enough info
to know how to generate the whole ctype category facets of a locale
instance.

In C++ it means that the following code will throw an exception to
signal that creation failed:

#include 
// Will throw a std::runtime_error exception.
std::locale loc(".utf8");

For the same reason building a locale with the ctype facets based on
UTF8 is also wrong:

// Will throw a std::runtime_error exception:
std::locale loc(locale::classic(), ".utf8", std::locale::ctype);

The only solution to get a locale instance that will handle utf8 encoding
is to specifically signal that the codecvt facet should be based on utf8
encoding:

// Will succeed if there is necessary platform support.
locale loc(locale::classic(), new codecvt_byname(".utf8"));

  Once you have obtain a locale instance you can inject it in a file stream to
read/write utf8 files:

std::fstream fstr("file.utf8");
fstr.imbue(loc);

You can also access the facet directly to perform utf8 encoding/decoding operations:

typedef std::codecvt codecvt_t;
const codecvt_t& encoding = use_facet(loc);

Notes:

1. The dot ('.') is mandatory in front of utf8. This is a POSIX convention, locale
names have the following format:
language[_country[.encoding]]

Ex: 'fr_FR'
    'french'
    'ru_RU.koi8r'

2. utf8 encoding is only supported for the moment under Windows. The less common
utf7 encoding is also supported. 

V'è una certa STL (come quello da Apache - STDCXX, per esempio) che viene fornito con diversi locali. Ma in altre situazioni il locale dipende solo sul sistema.

Se si potesse utilizzare il nome "ru_RU.UTF-8" su un funzionamento del sistema, ciò non significa che gli altri sistemi hanno lo stesso nome per questo locale. Debian e le finestre hanno probabilmente altri nomi e questa è la ragione si dispone di un'eccezione di runtime.

Si consiglia di installare le localizzazioni che si desidera sul sistema prima. Oppure utilizzare uno STL che già dispongono di tale locale.

I miei centesimi ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top