diff --git a/json11.cpp b/json11.cpp index 88024e9..a4a0cb4 100644 --- a/json11.cpp +++ b/json11.cpp @@ -24,7 +24,9 @@ #include #include #include +#include #include +#include namespace json11 { @@ -321,6 +323,23 @@ bool Json::operator< (const Json &other) const { * Parsing */ +/* strtod_dot(str) + * + * Parse the number according to the JSON grammar, ignoring the current locale assuming that the + * string is already validated to comply with the JSON grammar. + */ +double strtod_dot(const char* str) { + // It is not correct to use ordinary strtod because it uses the locale and in some locales, + // for example, in ru_RU.UTF-8, the floating-point delimiter is "," but not "." as in JSON + // grammar. + const size_t str_length = strspn(str, "0123456789.eE+-"); + std::istringstream string_stream(std::string(str, str_length)); + string_stream.imbue(std::locale("C")); + double f = NAN; + string_stream >> f; + return f; +} + /* esc(c) * * Format char c suitable for printing in an error message. diff --git a/test.cpp b/test.cpp index 3712d10..7793982 100644 --- a/test.cpp +++ b/test.cpp @@ -252,6 +252,18 @@ JSON11_TEST_CASE(json11_test) { } +JSON11_TEST_CASE(json11_test_numbers) { + const std::string numbers = + R"({"numbers": [0, -0, 1, 42, 0.5, -0.5, 0.5e+1, 0.5E+1, 5.0e-1, 0.5e+12]})"; + const std::string expected_numbers = + R"({"numbers": [0, 0, 1, 42, 0.5, -0.5, 5, 5, 0.5, 500000000000]})"; + + std::string err; + const std::string numbers_json = Json::parse(numbers, err).dump(); + std::cout << "numbers_json: " << numbers_json << std::endl; + JSON11_TEST_ASSERT(numbers_json == expected_numbers); +} + #if JSON11_TEST_STANDALONE_MAIN static void parse_from_stdin() { @@ -277,6 +289,7 @@ int main(int argc, char **argv) { } json11_test(); + json11_test_numbers(); } #endif // JSON11_TEST_STANDALONE_MAIN