2012-09-07 31 views
6

là có cách chỉnh sửa std :: stod() để tăng số chữ số thập phân trong chuỗi (chuỗi thành gấp đôi) chuyển đổi và buộc nó sử dụng ngôn ngữ của Hoa Kỳ?Cách tinh chỉnh std :: stod (chuỗi thành kép) cho dấu tách thập phân và số chữ số

Tôi có một ứng dụng Qt có thể được chạy trong cả hai giao diện điều khiển hoặc gui chế độ:

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(); 
} 

Trong ứng dụng này, tôi có một chuỗi phương pháp gấp đôi so với kết thúc tốt đẹp C++ mới 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; 
} 

Rất tiếc, trong khi ở chế độ bảng điều khiển, chuỗi sẽ chuyển đổi gấp đôi mong đợi một chuỗi có dấu chấm làm dấu phân cách thập phân, trong chế độ gui, nó sẽ thay thế chuỗi bằng dấu phẩy. Hơn nữa, như trước đây tôi đã sử dụng istringstream:

istringstream totalSString(valueAsString); 
totalSString >> valueAsDouble; 

tôi nhận thấy rằng stod truncates kết quả gấp đôi lên chỉ 3 chữ số thập phân, ít hơn nhiều so istringstream.

Vì vậy, có cách nào để tăng số chữ số thập phân và bắt buộc std :: stod để sử dụng ngôn ngữ của Hoa Kỳ cho chuyển đổi không?

Cảm ơn :-)

EDITED:

Nếu tôi thử kịch bản này:

// 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; 
    } 
} 

Tôi đã nhận những kết quả:

"console" chế độ:

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

"gui" chế độ:

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

Vì vậy, rõ ràng có cái gì đó ảnh hưởng đến stod() hành vi!

+1

'stod' được định nghĩa là sử dụng 'sprintf' với'% f'. Nó không thể cấu hình được. –

+0

Nếu bạn quan tâm đến tốc độ thời gian chạy thô và muốn độc lập về miền địa phương, và không quan tâm đến thời gian biên dịch tồi tệ hơn, [Boost.Spirit] (http://www.boost.org/libs/spirit/) .Qi là hoàn toàn là con đường để đi. – ildjarn

+0

Vượt qua điều này và đã bị sốc rằng stod cắt ngắn các giá trị. Nhưng vấn đề là std :: cout không xuất ra toàn bộ giá trị. Bạn phải đặt độ chính xác cao hơn: std :: cout << std :: setprecision (16); – ead

Trả lời

7

std::stod và thân nhân của nó được thiết kế để cung cấp một đơn giản, chuyển đổi nhanh chóng từ một chuỗi đến một số loại. (tiết lộ đầy đủ: đó là thiết kế của tôi) Vì vậy, không, không có miền địa phương; những gì bạn thấy là những gì bạn nhận được.

+0

Vì vậy, chỉ vì tò mò, tại sao tôi có hành vi khác này trong chế độ gui/console? Phải có một cái gì đó mà các thư viện Qt đặt ảnh hưởng đến hành vi stod. – Antonello

+0

@Antonello - xin lỗi, tôi không có kinh nghiệm với Qt. –

+2

Chỉ để làm rõ, stod() bị ảnh hưởng bởi miền địa phương hiện tại, ít nhất là trong GCC. Vì vậy, ví dụ để chắc chắn nó sẽ sử dụng dấu chấm như dấu tách thập phân nên sử dụng #include và setlocale (LC_ALL, "C") (đó là mặc định, nhưng rõ ràng Qt phải đặt nó thành ngôn ngữ máy tính đang chạy để bạn cần ghi đè ghi đè Qt ;-)) – Antonello

1

std::stod là cách thức tổng quát bằng cách chuyển đổi std::string thành gấp đôi. Nếu bạn muốn một cái gì đó cụ thể hơn, bạn nên thực hiện nó cho mình.

Ví dụ:

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

có đây là những gì tôi đã thực sự sử dụng, nhưng nó khá chậm, và tôi khá quan tâm đến tốc độ .. – Antonello

+0

Vâng, câu hỏi là "làm thế nào để tếch std :: stod". Câu trả lời đáng buồn là "bạn không thể".Nếu bạn thực sự phát hiện ra rằng việc sử dụng stringstreams là một nút cổ chai trong mã của bạn, bạn nên tối ưu hóa nó. Nhưng hãy nhớ, đừng tối ưu hóa sớm. – mfontanini

Các vấn đề liên quan