英文:
when running a function from my project, the stod() function gives an incorrect result
问题
Here's the translated portion of your text without code:
我有三个文件 - 一个json文件,我的项目,和测试(main.cpp)
json文件:
{
"points": {
"range": 25,
"step": 0.001
}
}
在main.cpp
文件中有这段代码:
#include <iostream>
#include <fstream>
#include <string>
#include <nlohmann/json.hpp>
using std::cout;
using std::endl;
using std::string;
using json = nlohmann::json;
int main()
{
std::ifstream jsonFile("json/settings.json");
json parsedFile = json::parse(jsonFile);
jsonFile.close();
double parsed_number;
printf("string: %s\nstod返回: %f\n",
parsedFile["points"]["step"].dump().c_str(),
stod(parsedFile["points"]["step"].dump()));
printf("类型: %s\n", typeid(stod(parsedFile["points"]["step"].dump())).name());
parsed_number = stod(parsedFile["points"]["step"].dump());
printf("步长: %f\n", parsed_number);
std::string temporary = "0.001";
parsed_number = stod(temporary);
printf("临时: %s \n步长: %f \n", temporary.c_str(), parsed_number);
}
这是正确的答案。
但在我的项目中,相同的代码:
std::ifstream jsonFile(json_filename);
assert(jsonFile.is_open());
json parsedFile = json::parse(jsonFile);
jsonFile.close();
double parsed_number;
printf("string: %s\nstod返回: %f\n",
parsedFile["points"]["step"].dump().c_str(),
stod(parsedFile["points"]["step"].dump()));
printf("类型: %s\n", typeid(stod(parsedFile["points"]["step"].dump())).name());
parsed_number = stod(parsedFile["points"]["step"].dump());
printf("步长: %f\n", parsed_number);
std::string temporary = "0.001";
parsed_number = stod(temporary);
printf("临时: %s \n步长: %f \n", temporary.c_str(), parsed_number);
也就是说,在我的项目中,从字符串"0.001"
中得到数字0
,而在测试文件中,得到了正确的0.001
。
我试图看看stod(parsedFile["points"]["step"].dump())
返回了什么。
我也尝试将string
转换为double
,你可以自己看结果。
如何在不使用临时解决方法的情况下解决这个问题?
C++20标准。
我找不到任何关于这个问题的答案...
英文:
I have three files - a json file, my project, and test (main.cpp)
json file:
{
"points": {
"range": 25,
"step": 0.001
}
}
in file main.cpp
this code:
#include <iostream>
#include <fstream>
#include <string>
#include <nlohmann/json.hpp>
using std::cout;
using std::endl;
using std::string;
using json = nlohmann::json;
int main()
{
std::ifstream jsonFile("json/settings.json");
json parsedFile = json::parse(jsonFile);
jsonFile.close();
double parsed_number;
printf("string: %s\nstod return: %f\n",
parsedFile["points"]["step"].dump().c_str(),
stod(parsedFile["points"]["step"].dump()));
printf("type: %s\n", typeid(stod(parsedFile["points"]["step"].dump())).name());
parsed_number = stod(parsedFile["points"]["step"].dump());
printf("step: %f\n", parsed_number);
std::string temporary = "0.001";
parsed_number = stod(temporary);
printf("temporary: %s \nstep: %f \n", temporary.c_str(), parsed_number);
}
/* outputs:
string: 0.001
stod returns: 0.001000
type: d
step: 0.001000
temporary: 0.001
step: 0.001000
*/
This is the correct answer.
But in my project, the same code:
std::ifstream jsonFile(json_filename);
assert(jsonFile.is_open());
json parsedFile = json::parse(jsonFile);
jsonFile.close();
//range = stoi(parsedFile["points"]["range"].dump());
double parsed_number;
printf("string: %s\nstod returns: %f\n",
parsedFile["points"]["step"].dump().c_str(),
stod(parsedFile["points"]["step"].dump()));
printf("type: %s\n", typeid(stod(parsedFile["points"]["step"].dump())).name());
parsed_number = stod(parsedFile["points"]["step"].dump());
printf("step: %f\n", parsed_number);
std::string temporary = "0.001";
parsed_number = stod(temporary);
printf("temporary: %s \nstep: %f \n", temporary.c_str(), parsed_number);
/* outputs:
string: 0.001
stod returns: 0,000000
type: d
step: 0,000000
temporary: 0.001
step: 0,000000
*/
That is, from the string "0.001"
in my project, the number 0
is obtained, and in the test file, the correct 0.001
.
I tried to see what stod(parsedFile["points"]["step"].dump())
returns.
I also tried to convert string
to double, you can see the result for yourself.
How can I get around this problem without using crutches?
C++20 standard.
I can't find any answers to this...
答案1
得分: 2
你应该使用库函数 get<T>()
从 json
对象中提取值,而不是自己使用 std::stod
,因为它受当前区域设置的影响。
在你的情况下:
double parsed_number = parsedFile["points"]["step"].get<double>();
你还可以创建一个 from_json
重载,直接填充对象,如果你愿意的话:
#include <nlohmann/json.hpp>
#include <fstream>
#include <iostream>
using json = nlohmann::json;
json read_json_file() {
if (std::ifstream jsonFile("json/settings.json"); jsonFile) {
return json::parse(jsonFile);
}
return {};
}
struct points {
int range;
double step;
};
void from_json(const json& j, points& p) {
auto& jpnts = j.at("points");
jpnts.at("range").get_to(p.range);
jpnts.at("step").get_to(p.step);
}
int main() {
auto parsedFile = read_json_file();
auto pnts = parsedFile.get<points>();
std::cout << pnts.range << '\n' << pnts.step << '\n';
}
英文:
You should use the library function get<T>()
to extract the value from the json
object and not do it yourself with std::stod
which is affected by the current locale.
In your case:
double parsed_number = parsedFile["points"]["step"].get<double>();
You could also create a from_json
overload an populate objects directly if you wish:
#include <nlohmann/json.hpp>
#include <fstream>
#include <iostream>
using json = nlohmann::json;
json read_json_file() {
if(std::ifstream jsonFile("json/settings.json"); jsonFile) {
return json::parse(jsonFile);
}
return {};
}
struct points {
int range;
double step;
};
void from_json(const json& j, points& p) {
auto& jpnts = j.at("points");
jpnts.at("range").get_to(p.range);
jpnts.at("step").get_to(p.step);
}
int main() {
auto parsedFile = read_json_file();
auto pnts = parsedFile.get<points>();
std::cout << pnts.range << '\n' << pnts.step << '\n';
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论