Skip to content

lexer::get_number return NAN #82

Closed

Description

@Ingener74

screenshot_2015-06-04_09-12-02

Activity

  1. nlohmann commented on Jun 4, 2015

    @nlohmann
    Owner

    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.

  2. Ingener74 commented on Jun 4, 2015

    @Ingener74
    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.

  3. nlohmann commented on Jun 4, 2015

    @nlohmann
    Owner

    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?
  4. self-assigned this
    on Jun 4, 2015
  5. Ingener74 commented on Jun 4, 2015

    @Ingener74
    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

  6. nlohmann commented on Jun 4, 2015

    @nlohmann
    Owner

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

  7. Ingener74 commented on Jun 4, 2015

    @Ingener74
    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

  8. Ingener74 commented on Jun 4, 2015

    @Ingener74
    Author

    maybe some compilation flags needed?

  9. added a commit that references this issue on Jun 4, 2015
  10. nlohmann commented on Jun 4, 2015

    @nlohmann
    Owner

    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.

  11. nlohmann commented on Jun 4, 2015

    @nlohmann
    Owner

    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.

  12. Ingener74 commented on Jun 5, 2015

    @Ingener74
    Author

    Sorry Niels. Problem was in my library :)

  13. Ingener74 commented on Jun 5, 2015

    @Ingener74
    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

  14. nlohmann commented on Jun 7, 2015

    @nlohmann
    Owner

    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

Metadata

Metadata

Assignees

Labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions