当运行我的项目中的一个函数时,stod()函数返回了一个不正确的结果。

huangapple go评论68阅读模式
英文:

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:

{
    &quot;points&quot;: {
        &quot;range&quot;: 25,
        &quot;step&quot;: 0.001
    }
}

in file main.cpp this code:

#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;string&gt;
#include &lt;nlohmann/json.hpp&gt;


using std::cout;
using std::endl;
using std::string;
using json = nlohmann::json;


int main()
{
    std::ifstream jsonFile(&quot;json/settings.json&quot;);
    json parsedFile = json::parse(jsonFile);
    jsonFile.close();

    double parsed_number;
    printf(&quot;string: %s\nstod return: %f\n&quot;, 
           parsedFile[&quot;points&quot;][&quot;step&quot;].dump().c_str(), 
           stod(parsedFile[&quot;points&quot;][&quot;step&quot;].dump()));

    printf(&quot;type: %s\n&quot;, typeid(stod(parsedFile[&quot;points&quot;][&quot;step&quot;].dump())).name());
    
    parsed_number = stod(parsedFile[&quot;points&quot;][&quot;step&quot;].dump());
    printf(&quot;step: %f\n&quot;, parsed_number);

    std::string temporary = &quot;0.001&quot;;
    parsed_number = stod(temporary);
    printf(&quot;temporary: %s \nstep: %f \n&quot;, 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[&quot;points&quot;][&quot;range&quot;].dump());

    double parsed_number;
    printf(&quot;string: %s\nstod returns: %f\n&quot;, 
           parsedFile[&quot;points&quot;][&quot;step&quot;].dump().c_str(), 
           stod(parsedFile[&quot;points&quot;][&quot;step&quot;].dump()));

    printf(&quot;type: %s\n&quot;, typeid(stod(parsedFile[&quot;points&quot;][&quot;step&quot;].dump())).name());
    
    parsed_number = stod(parsedFile[&quot;points&quot;][&quot;step&quot;].dump());
    printf(&quot;step: %f\n&quot;, parsed_number);

    std::string temporary = &quot;0.001&quot;;
    parsed_number = stod(temporary);
    printf(&quot;temporary: %s \nstep: %f \n&quot;, 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 &quot;0.001&quot; in my project, the number 0 is obtained, and in the test file, the correct 0.001.

I tried to see what stod(parsedFile[&quot;points&quot;][&quot;step&quot;].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&lt;T&gt;() 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[&quot;points&quot;][&quot;step&quot;].get&lt;double&gt;();

You could also create a from_json overload an populate objects directly if you wish:

#include &lt;nlohmann/json.hpp&gt;

#include &lt;fstream&gt;
#include &lt;iostream&gt;

using json = nlohmann::json;

json read_json_file() {
    if(std::ifstream jsonFile(&quot;json/settings.json&quot;); jsonFile) {
        return json::parse(jsonFile);
    }
    return {};
}

struct points {
    int range;
    double step;
};

void from_json(const json&amp; j, points&amp; p) {
    auto&amp; jpnts = j.at(&quot;points&quot;);
    jpnts.at(&quot;range&quot;).get_to(p.range);
    jpnts.at(&quot;step&quot;).get_to(p.step);
}

int main() {
    auto parsedFile = read_json_file();
    auto pnts = parsedFile.get&lt;points&gt;();

    std::cout &lt;&lt; pnts.range &lt;&lt; &#39;\n&#39; &lt;&lt; pnts.step &lt;&lt; &#39;\n&#39;;
}

huangapple
  • 本文由 发表于 2023年4月7日 05:14:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/75953838.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定