2012-09-07 17 views
6

esiste un modo per modificare std :: stod() per aumentare il numero di cifre decimali nel (stringa da raddoppiare) conversione e costringerlo a usare le impostazioni locali americane?Come modificare std :: stod (stringa da raddoppiare) per separatore decimale e numero di cifre

Ho un'applicazione Qt che può essere eseguito sia in modalità console o GUI:

if (opt->getFlag('c') || opt->getFlag("console")){ 
    ThreadManager modelMainThread; 
    modelMainThread.runFromConsole(inputFileName,scenarioName); 
} 
else { 
    QApplication app(argc, argv); 
    MainWindow mainWin; 
    mainWin.show(); 
    return app.exec(); 
} 

All'interno di questa applicazione ho una stringa in doppio metodo che avvolge la nuova C++ 11 stod:

double s2d (const string &string_h) const { 
    try { 
    return stod(string_h); 
    } catch (...) { 
    if (string_h == "") return 0; 
    else { 
     cout << "error!" << endl; 
    } 
    } 
    return 0; 
} 

Abbastanza strano, mentre in modalità console la stringa da raddoppiare prevede una stringa con punto come separatore decimale, in modalità gui prevede invece una stringa con virgola. Inoltre, come ero in precedenza usando istringstream:

istringstream totalSString(valueAsString); 
totalSString >> valueAsDouble; 

ho notato che stod tronca la risultante doppia a soli 3 cifre decimali, molto meno istringstream.

Quindi esiste un modo per aumentare il numero di cifre decimali e forzare std :: stod a utilizzare le impostazioni locali statunitensi per la conversione?

Grazie :-)

CURA:

Se provo questo script:

// testing stod() .. 
vector<string> numbers; 
numbers.push_back("123.1234567890"); 
numbers.push_back("123.1234"); 
numbers.push_back("123,1234567890"); 
numbers.push_back("123,1234"); 
double outd; 
for(uint i=0;i<numbers.size();i++){ 
    try { 
     outd = stod(numbers[i]); 
     cout << "Conversion passed: " << numbers[i] << " - " << outd << endl; 
    } catch (...) { 
     cout << "Conversion DID NOT passed: " << numbers[i] << " - " <<endl; 
    } 
} 

ho ottenuto questi risultati:

modalità "console":

Conversion passed: 123.1234567890 - 123.123 
Conversion passed: 123.1234 - 123.123 
Conversion passed: 123,1234567890 - 123 
Conversion passed: 123,1234 - 123 

modalità "gui":

Conversion passed: 123.1234567890 - 123 
Conversion passed: 123.1234 - 123 
Conversion passed: 123,1234567890 - 123.123 
Conversion passed: 123,1234 - 123.123 

Quindi, chiaramente c'è qualcosa che influenza stod() comportamento!

+1

'stod' è definito come usando' sprintf' con '% f'. Non è configurabile –

+0

Se si è interessati alla velocità di runtime non elaborata e si desidera l'indipendenza delle impostazioni locali e non si preoccupano dei tempi di compilazione potenzialmente peggiori, [Boost.Spirit] (http://www.boost.org/libs/spirit/) .Qi è assolutamente la strada da percorrere – ildjarn

+0

Inciampato su questo e fu scioccato che stod tronca i valori. Ma il problema è che std :: cout non produce l'intero valore. È necessario impostare una maggiore precisione: std :: cout << std :: setprecision (16); – ead

risposta

7

std::stod ei suoi parenti sono stati progettati per fornire un semplice, rapida conversione da una stringa in un tipo numerico. (completa divulgazione: è il mio progetto) Quindi, no, nessun locale; Quello che vedi è quello che ottieni.

+0

Quindi, solo per curiosità, perché ho questo comportamento diverso in modalità gui/console? Deve esserci qualcosa che le librerie Qt impostano che influenzano il comportamento di stod. – Antonello

+0

@Antonello - scusa, non ho esperienza con Qt. –

+2

Solo per chiarimenti, stod() È influenzato dalle impostazioni locali correnti, almeno in GCC. Per esempio, per essere sicuri che userà il punto come separatore decimale, dovresti usare #include e setlocale (LC_ALL, "C") (questo è l'impostazione predefinita, ma chiaramente Qt deve impostarlo sulle impostazioni locali del computer in esecuzione, quindi devi eseguire l'override l'override di Qt ;-)) – Antonello

1

std::stod è un modo in qualche modo generico di convertire un std::string in un doppio. Se vuoi qualcosa di più specifico, dovresti implementarlo tu stesso.

Ad esempio:

double my_stod(const std::string &valueAsString) { 
    istringstream totalSString(valueAsString); 
    double valueAsDouble; 
    // maybe use some manipulators 
    totalSString >> valueAsDouble; 
    if(!totalSString) 
     throw std::runtime_error("Error converting to double");  
    return valueAsDouble; 
} 
+0

sì, questo è quello che stavo effettivamente usando, ma è piuttosto lento, e sono piuttosto preoccupato per la velocità .. – Antonello

+0

Bene, la domanda era "come teak std :: stod". La risposta è tristemente "non puoi".Se si scopre veramente che l'uso di stringstreams è un collo di bottiglia nel codice, è necessario ottimizzarlo. Ma ricorda, non ottimizzare in modo prematuro. – mfontanini

Problemi correlati