2009-10-07 19 views
11

Più lavoro con le sfaccettature locali di C++, più capisco --- sono interrotte.Esistono aggiornamenti del supporto per la localizzazione in C++ 0x?

  • std::time_get - non è simmetrica con std::time_put (come in C strftime/strptime) e non consente facili analisi di volte con segni di AM/PM.
  • I discovered recentemente la semplice formattazione dei numeri può produrre UTF-8 illegale in determinate impostazioni locali (come ru_RU.UTF-8).
  • std::ctype è molto semplicistico supponendo che su superiore/inferiore possa essere eseguito su base per carattere (la conversione del caso può modificare il numero di caratteri ed è dipendente dal contesto).
  • std::collate - non supporta la forza di fascicolazione (maiuscole o minuscole).
  • Non c'è modo di specificare il fuso orario diverso dal fuso orario globale nella formattazione dell'ora.

E molto altro ancora ...

  • Fa qualcuno sa se tutti i cambiamenti sono attesi nel sfaccettature standard in C++ 0x?
  • C'è un modo per dare importanza a tali cambiamenti?

Grazie.

EDIT: chiarimenti caso il collegamento non è accessibile:

std::numpunct definisce migliaia separatore come char. Quindi, quando separatore in U + 2002 - diverso tipo di spazio non può essere riprodotto come singolo carattere in UTF-8 ma come sequenza di più byte.

In C API struct lconv definisce il separatore di migliaia come stringa e non soffre di questo problema. Quindi, quando provi a formattare numeri con separatori al di fuori di ASCII con le impostazioni internazionali UTF-8, viene generato UTF-8 non valido.

Per riprodurre il bug scrittura 1234 per std: ostream con imbevuta ru_RU.UTF-8 locale

EDIT2: devo ammettere che POSIX C localizzazione API funziona molto più agevole:

  • C'è inverso di strftime - - strptime (strftime fa lo stesso di std::time_put::put)
  • Nessun problema con la formattazione del numero a causa del punto che ho menzionato sopra.

Tuttavia, è ancora per essere perfecet.

Edit3: Secondo le ultime note su C++ 0x posso vedere che std::time_get::get - simile a strptime e di fronte di std::time_put::put.

+0

Sembra che tu abbia la fortuna di ottenere il funzionamento di std :: locale Non ho mai avuto alcun successo con MingW – UncleBens

+0

L'unico link nella tua risposta è rotto e non funziona non aperto (non è sorprendente dato che è '.no-ip.info', immagino, ma dato che è una parte della domanda, potresti volerlo mettere altrove in modo che sia accessibile). –

+0

Mingw non supporta alcuna impostazione locale accetta C/POSIX, tuttavia, sotto linux il supporto della localizzazione è molto buono, l'API della libreria C di BTW è molto più pulita, meglio progettata e in genere funziona molto più agevolmente, ma ... POSIX API consente solo un locale per processo che è piuttosto limitante – Artyom

risposta

1

std::numpunct è un modello. Tutte le specializzazioni cercano di restituire il carattere separatore decimale.Ovviamente, in qualsiasi locale in cui si tratta di un carattere ampio, è necessario utilizzare std::numpunct<wchar_t>, in quanto la specializzazione <char non può farlo.

Detto questo, C++ 0x è praticamente fatto. Tuttavia, se i buoni miglioramenti continuano, è probabile che il comitato C++ avvii C++ 1x. È molto probabile che il comitato ISO C++ accetti il ​​tuo aiuto, se offerto attraverso la tua organizzazione nazionale membro ISO. Vedo che Pavel Minaev ha suggerito un rapporto sui difetti. Questo è tecnicamente possibile, ma i problemi che descrivi sono in generale limiti di progettazione. In tal caso, la soluzione più affidabile è progettare una libreria Boost per questo, far passare la recensione di Boost, inviarla per l'inclusione nello standard e partecipare alle riunioni di ISO C++ per affrontare eventuali problemi che si verificano lì.

+0

"si dovrebbe usare std :: numpunct ", wchar_t è uno dei modi per fornire punto Unicode ". Cosa succede se tale punto viene collocato al di fuori del BMP e sizeof == (wchar_t) 2? E se tale la separazione è composta da più di un carattere? Questo è esattamente lo stesso problema! Anche quando si utilizzano le impostazioni internazionali UTF-8, è necessario prevedere che i caratteri possano essere più larghi di 1 byte. La soluzione corretta è fornire invece (risultato CharT const *) di CharT. In ogni caso, quando si scrive un programma semplice che stampa i numeri ci si aspetta che gestisca correttamente l'Unicode, come in C localization. – Artyom

+0

Il design di 'wchar_t' è tale che un singolo' wchar_t' può contenere qualsiasi carattere supportato dall'implementazione. Per questo motivo, un'implementazione con wchar_t a 16 bit non può supportare tutti i caratteri Unicode 5.0. Dovrebbe scegliere un sottoinsieme supportato, come il BMP. Non c'è nulla di simile in ISO C++ come una "stringa multi-wchar_t". Tuttavia, un'implementazione è libera di definire un '__char16' o un' __char32' e specializzare 'std :: numpunct <>' per loro. – MSalters

+0

"un'implementazione con 16-bit wchar_t non può supportare tutto Unicode 5.0" Non può supportare tutto l'Unicode 2.0 dove sono stati introdotti i primi caratteri surrogati. "Non c'è nulla di simile in ISO C++ come una" stringa multi-wchar_t "" - Che dire di UTF-16? 'wchar_t const *' sta perfettamente bene. Dai un'occhiata qui: http://linux.die.net/man/7/locale. Il separatore delle migliaia è rappresentato come 'char *' in 'struct lconv', quindi non c'è alcun problema a rappresentare un qualsiasi carattere Unicode con le impostazioni internazionali UTF-8. – Artyom

4

Sono d'accordo con te, il C++ è privo del supporto i18n corretto.

Qualcuno sa se sono previste modifiche in facet standard in C++ 0x?

È troppo tardi nel gioco, quindi probabilmente no.

C'è un modo per dare importanza a tali cambiamenti?

Sono molto pessimista su questo.

Se richiesto direttamente, Stroustrup ha affermato di non vedere alcun problema con lo stato corrente. E un altro dei grandi C++ (autore di libri e tutti) non si è nemmeno reso conto che wchar_t può essere un byte, se leggi lo standard.

E alcuni thread in boost (che sembra guidare la direzione in futuro) mostrano così poca comprensione su come funziona che è assolutamente spaventoso.

C++ 0x ha aggiunto a malapena alcuni tipi di dati di caratteri Unicode, in ritardo nel gioco e dopo un sacco di difficoltà. Non sto trattenendo il respiro per troppo presto.

Immagino che l'unica possibilità di vedere qualcosa di meglio sia se qualcuno veramente buono/rispettato nei mondi i18n e C++ sia direttamente coinvolto nella prossima versione dello standard. - (