Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lexer::get_number return NAN #82

Closed
Ingener74 opened this issue Jun 4, 2015 · 12 comments
Closed

lexer::get_number return NAN #82

Ingener74 opened this issue Jun 4, 2015 · 12 comments
Assignees

Comments

@Ingener74
Copy link

screenshot_2015-06-04_09-12-02

@nlohmann
Copy link
Owner

nlohmann commented Jun 4, 2015

Could you please provide more information. From the screenshot, I do not understand where the NAN occurred. Maybe a small example of an input JSON and the code you are using would help.

@Ingener74
Copy link
Author

Example json on screenshot, is Box.json. get_number fail on ["origin"]["x"]
in top right you can see pointers values.
strdot return 0, but m_start and endptr not equal, end get_number method returns NAN, maybe strtod fail, or work wrong? i can't yet understand.

@nlohmann
Copy link
Owner

nlohmann commented Jun 4, 2015

I see. However, I cannot reproduce this - there are several test cases to check get_number. Could you attach the JSON file and give me more information:

  • What exactly are you calling?
  • What OS/compiler do you use?

@nlohmann nlohmann self-assigned this Jun 4, 2015
@Ingener74
Copy link
Author

I call next

json j;
file->getStream() >> j; // here getStream() return istream&

this in >> operator when json parse file

Computer where i repeat error is
OS: Xubuntu 15.04
uname -a: Linux pavel 3.19.0-16-generic #16-Ubuntu SMP Thu Apr 30 16:09:58 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

Compiler: g++ (Ubuntu 4.8.4-1ubuntu15) 4.8.4

@nlohmann
Copy link
Owner

nlohmann commented Jun 4, 2015

Could you please also attach the JSON file (or email it to me)?

@Ingener74
Copy link
Author

I try simple example

{
    "Test":"Test1",
    "Number":100,
    "Foo":42.42
}
    json j;
    ifstream f("/home/pavel/workspace/Jupiter/samples/Box/Box.json");
    f >> j;

    string test = j["Test"];
    cout << "test " << test << endl;

    int number = j["Number"];
    cout << "number" << number << endl;

    float foo = j["Foo"];
    cout << "foo " << foo << endl;

and got output

std::exception: parse error - 100 is not a number

I found out that the reason is not the compiler, not in your library, and not in the json file because another program on this computer with this file it works. But I do not understand why it does not work here. It may be needed to determine what is or to declare further

@Ingener74
Copy link
Author

maybe some compilation flags needed?

nlohmann added a commit that referenced this issue Jun 4, 2015
@nlohmann
Copy link
Owner

nlohmann commented Jun 4, 2015

Thanks for the details. However, I cannot reproduce them - with the latest commit, I added a test case of the code you posted above, and it succeeds on OSX and Linux.

@nlohmann
Copy link
Owner

nlohmann commented Jun 4, 2015

I also tried the file you sent me with this code:

#include <fstream>
#include <json.hpp>

using namespace nlohmann;
using namespace std;

int main() {
    json j;
    ifstream f("Box.json");
    f >> j;

    std::cout << j["rigidBodies"][0]["origin"]["x"] << std::endl;
}

Compiled with g++ test2.cpp -o test2 -std=c++11 -Isrc.

The output is as expected: 0.

@Ingener74
Copy link
Author

Sorry Niels. Problem was in my library :)

@Ingener74
Copy link
Author

Niels sorry again. Found an error which indirectly touches your library function in some rare cases, it does not work properly due to the fact that you have a different locale, and she considers the comma separator instead of a period, and then the library does not begin to parse correctly.

inline number_float_t get_number() const
{
    // conversion
    typename string_t::value_type* endptr;
    const auto float_val = std::strtod(reinterpret_cast<typename string_t::const_pointer>(m_start),
                                               &endptr); // strtod, locale depends, comma instead dot for float

    // return float_val if the whole number was translated and NAN
    // otherwise
    return (reinterpret_cast<lexer_char_t*>(endptr) == m_cursor) ? float_val : NAN;
}

It helped me next

    setlocale(LC_NUMERIC, "C");

    json j;
    file->getStream() >> j;

I found the solution here http://www.thecodingforums.com/threads/how-to-make-std-strtod-not-depend-on-locale.546559/

I thought maybe you check locale before parsing file

@Ingener74 Ingener74 reopened this Jun 5, 2015
@nlohmann
Copy link
Owner

nlohmann commented Jun 7, 2015

I see the problem. The linked solution is not really an option, because setting the locale affects the whole program, and not just the JSON class. I see if I can find a different approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants