[英]C++: strod() and atof() are not returning double as expected
我正在嘗試使用從 a.txt 文件中獲得的值將字符串變成雙精度值。
我獲得的雙打沒有小數點。 我認為這是因為在.txt 中,數字的小數點由逗號而不是點分隔。 但我不知道如何解決。
這是我的代碼的簡化:
#include <iostream>
#include <fstream> // read text file
#include <stdlib.h> // strtod, atof
int main() {
std::ifstream readWindData("winddata.txt");
// check that document has been opened correctly
if (!readWindData.is_open()) {
std::cout << "Wind data could not be opened." << std::endl;
return 1;
}
// skip headers of the table
std::string firstLine;
std::getline(readWindData, firstLine);
int numberOfRows = 0; // variable to count rows of the table
// initialise strings that separate each value
std::string time, string u10st, u40st, u60st, u80st, u100st,
u116st, u160st, dir10st, dir60st, dir100st, timeDecst;
// initialise doubles
double u10, u40, u60, u80, u100, u116, u160, dir10, dir60, dir100, timeDec;
std::string nextLine;
// Read strings and turn it into doubles line by line until end
while (readWindData >> time >> u10st >> u40st >> u60st >> u80st >> u100st
>> u116st >> u160st >> dir10st >> dir60st >> dir100st >> timeDecst) {
// try two different functions to turn strings into doubles:
u10 = strtod(u10st.c_str(), NULL);
u40 = atof(u40st.c_str());
// ensure numbers are displaying all their decimals
std::cout.precision(std::numeric_limits<double>::digits10 + 1);
// see what I am getting
std::cout << time << " " << u10st << " " << u10 << " " << u40 << "\n";
std::getline(readWindData, nextLine); // this line skips some crap on the side of some rows
numberOfRows++; // counts rows
}
std::cout << "Number of rows = " << numberOfRows << "\n";
readWindData.close();
return 0;
}
這是文件的三行:
time (hour) u10(m/s)u40(m/s)u60 (m/s)u80(m/s)u100(m/s)u116(Um/s)u160(m/s)dir10 dir60 dir100 time decimal hours
00:00 4,25636 7,18414 8,56345 9,75567 10,9667 12,1298 13,8083 110,616 131,652 141,809 0 midnight
00:10 4,54607 7,40763 8,62832 9,91782 11,2024 12,2694 14,1229 114,551 133,624 142,565 0,166666667
這些是用上面的代碼輸出的那些行:(提醒,我 std::cout time (string), u10st (string), u10 (double), u40 (double))。
00:00 4,25636 4 7
00:10 4,54607 4 7
關於如何將 4,25636 字符串讀入雙精度 4.25636 有什么想法嗎? 文件太長,無法修改。
浮點數使用逗號小數點分隔符,您需要句點。
這表明數據是使用與您不同的語言環境序列化的。
要解決此問題,請在解析數字之前設置您的語言環境(然后再恢復)。
例如,下面是一些使用默認句點分隔符解析數字“12,34”的代碼,然后我們將語言環境設置為丹麥並重試:
const char* number = "12,34";
double parsed_number = 0;
parsed_number = std::strtod(number, nullptr);
std::cout << "parsed number in default locale: " << parsed_number << std::endl;
std::cout << "Setting locale to Denmark (comma decimal delimiter)" << std::endl;
std::locale::global(std::locale("en_DK.utf8"));
parsed_number = std::strtod(number, nullptr);
std::cout << "parsed number in Denmark locale: " << parsed_number << std::endl;
//restore default locale
std::locale::global(std::locale(""));
Output:
默認語言環境中解析的數字:12
將語言環境設置為丹麥(逗號十進制分隔符)
在丹麥語言環境中解析的數字:12.34
詢問周圍的人,看看是誰序列化了這些數據,並獲得正確的語言環境。 您可以使用locale -a
在 *nix 系統中找到可用的語言環境
在 Windows 上似乎有點困難
為避免弄亂全局語言環境,您只需將,
替換為.
在調用strtod()
之前
std::replace(u10st.begin(), u10st.end(), ',', '.');
u10 = strtod(u10st.c_str(), nullptr);
但是在上面顯示的程序中,如果您使用逗號作為小數點分隔符的語言環境,您也可以使用運算符>>
直接從ifstream
讀取到double
。
readWindData.imbue(std::locale("de_DE.UTF-8")); // or fr, nl, ru, etc.
double u10, u40, u60, u80, u100, u116, u160, dir10, dir60, dir100, timeDec;
while (readWindData >> time >> u10 >> u40 >> u60 >> u80 >> u100
>> u116 >> u160 >> dir10 >> dir60 >> dir100 >> timeDec) {
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.