2009-06-17 11 views
7

Un problema internazionale comune è la conversione di valori doppi rappresentati nelle stringhe. Questa roba si trova in molte aree.conversione stringa doppia e locale

A partire con i file CSV che si sia chiamati

comma separated 

o

character separated 

perché a volte questi vengono memorizzati come

1.2,3.4 
5.6,6.4 

nelle regioni inglesi o

1,2;3,4 
5,6;6,4 

in ad esempio regioni tedesche.

Da questo sfondo, è in qualche modo necessario sapere che la maggior parte dei metodi std :: sono dipendenti dalle impostazioni internazionali. Quindi in Germania, leggeranno "1,2" come 1,2 e lo riscriveranno come "1,2" ma con un sistema operativo inglese leggerà "1,2" come 1 e lo scriverà come "1".

Poiché la locale è uno stato globale dell'applicazione, non è consigliabile passare a un'impostazione diversa; e qui ci sono alcuni problemi quando devo leggere un file CSV tedesco su una macchina inglese o viceversa.

È anche difficile scrivere codice che si comporta allo stesso modo su tutte le macchine. Il flusso C++ consente un'impostazione locale per flusso.

class Punctation : public numpunct<wchar_t> 
{ 
public: 

    typedef wchar_t char_type; 
    typedef std::wstring string_type; 

    explicit Punctation(const wchar_t& decimalPoint, std::size_t r = 0) : 
    decimalPoint_(decimalPoint), numpunct<wchar_t>(r) 
    { 
    } 

    Punctation(const Punctation& rhs) : 
    decimalPoint_(rhs.decimalPoint_) 
    { 
    } 

protected: 

    virtual ~Punctation() 
    { 
    }; 

    virtual wchar_t do_decimal_point() const 
    { 
    return decimalPoint_; 
    } 

private: 

    Punctation& operator=(const Punctation& rhs); 

    const wchar_t decimalPoint_; 
}; 

... 

std::locale newloc(std::locale::classic(), new Punctation(L',')); 
stream.imbue(newloc); 

consente di inizializzare un flusso con comportamento std :: C e sostituire solo il punto decimale. Questo mi dà la possibilità di ignorare il separatore delle migliaia, che può anche influire. Il tedesco 1000,12 può diventare "1.000,12"; o in inglese "1,000.12" finirà in completa confusione. Anche sostituendo "," con "." non aiuterà in questa situazione.

Se devo lavorare con atof e gli amici posso usare

const char decimal_point = *(localeconv()->decimal_point); 

a pimp il mio comportamento.

Quindi c'è una quantità terribile di cose solo per il doppio comportamento internazionale. Anche il mio Visual Studio ha dei problemi perché la versione tedesca vuole scrivere 8,0 come versione nel file vcproj mentre una versione inglese vuole cambiarlo in 8.0, cosa che è avvenuta in modo definitivo per caso perché in XML è definito come 8.0 in tutto paesi del mondo.

Quindi volevo solo descrivere il problema un po 'per chiedere aspetti che potrei aver ignorato. cose che so:

  • pinta decimale dipende dal locale
  • 000 separatore dipende dal locale
  • esponente dipende dal locale

//     German  English  Also known 
// decimal point  ,   .    
// exponent   e/E   e/E   d/D 
// thousand sep  .   , 

Quale paese utilizza quale impostazione?Forse puoi aggiungermi degli esempi interessanti che non avevo fino ad ora.

+0

http://en.wikipedia.org/wiki/Decimal_point#Examples_of_use – Pod

risposta

-1

Penso che stiate cercando Appendix D of The C++ Programming Language. Potresti essere interessato al fatto che è possibile avere più locali in uso alla volta in un programma.

+0

Perché il downvote? –

2

Non usare mai atof (s). È una rapida scorciatoia & per strtod (s, 0) senza segnalazione degli errori. (Lo stesso vale per atoi() e strtol().)

Se una funzione pubblicizzato per restituire un codice di errore in caso di difficoltà, tu controllo shalt per quel codice, sì, anche se i controlli il triplo del tuo codice e produci dolori alle tue dita digitanti, perché se pensi che "non può succedere a me ", gli dei ti puniranno sicuramente per la tua arroganza.

(Henry Spencer, "dieci comandamenti per il C Programmer", Comandamento # 6)

Problemi correlati