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

dump() convert strings encoded by utf-8 to shift-jis on windows 10. #147

Closed
silverist opened this issue Nov 14, 2015 · 4 comments
Closed

Comments

@silverist
Copy link

when I dump() a json object as follows, the dumped string is converted from "utf-8" to "shift-jis".
How can I do to keep up its encode "utf-8"?

{
   "data":"[[0,1,2,3,4],[0,1,2,3,4]]",
   "status":1
}
@nlohmann
Copy link
Owner

What do you mean? What output do you expect?

@silverist
Copy link
Author

sorry, the type of "data" element is not "array" but "string".
(And the string is encoced by "utf-8".)

As the source of json.hpp, dump() seems to call the method at line 4716.
Then, execute the following section because the type of "data" element is "string", I think.
And I guess the "data" string is converted from "utf-8" to "shift-jis" when execute the following section.
(in other words, converted by std::ostream& o or escape_string function)

            case (value_t::string):
            {
                o << string_t("\"") << escape_string(*m_value.string) << "\"";
                return;
            }

■dump() in json.hpp at line 4716

    void dump(std::ostream& o, const bool pretty_print, const unsigned int indent_step,
              const unsigned int current_indent = 0) const
    {
        // variable to hold indentation for recursive calls
        unsigned int new_indent = current_indent;

        switch (m_type)
        {
            case (value_t::object):
            {
                if (m_value.object->empty())
                {
                    o << "{}";
                    return;
                }

                o << "{";

                // increase indentation
                if (pretty_print)
                {
                    new_indent += indent_step;
                    o << "\n";
                }

                for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
                {
                    if (i != m_value.object->cbegin())
                    {
                        o << (pretty_print ? ",\n" : ",");
                    }
                    o << string_t(new_indent, ' ') << "\""
                      << escape_string(i->first) << "\":"
                      << (pretty_print ? " " : "");
                    i->second.dump(o, pretty_print, indent_step, new_indent);
                }

                // decrease indentation
                if (pretty_print)
                {
                    new_indent -= indent_step;
                    o << "\n";
                }

                o << string_t(new_indent, ' ') + "}";
                return;
            }

            case (value_t::array):
            {
                if (m_value.array->empty())
                {
                    o << "[]";
                    return;
                }

                o << "[";

                // increase indentation
                if (pretty_print)
                {
                    new_indent += indent_step;
                    o << "\n";
                }

                for (auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
                {
                    if (i != m_value.array->cbegin())
                    {
                        o << (pretty_print ? ",\n" : ",");
                    }
                    o << string_t(new_indent, ' ');
                    i->dump(o, pretty_print, indent_step, new_indent);
                }

                // decrease indentation
                if (pretty_print)
                {
                    new_indent -= indent_step;
                    o << "\n";
                }

                o << string_t(new_indent, ' ') << "]";
                return;
            }

            case (value_t::string):
            {
                o << string_t("\"") << escape_string(*m_value.string) << "\"";
                return;
            }

            case (value_t::boolean):
            {
                o << (m_value.boolean ? "true" : "false");
                return;
            }

            case (value_t::number_integer):
            {
                o << m_value.number_integer;
                return;
            }

            case (value_t::number_float):
            {
                // 15 digits of precision allows round-trip IEEE 754
                // string->double->string; to be safe, we read this value from
                // std::numeric_limits<number_float_t>::digits10
                o << std::setprecision(std::numeric_limits<number_float_t>::digits10) << m_value.number_float;
                return;
            }

            case (value_t::discarded):
            {
                o << "<discarded>";
                return;
            }

            default:
            {
                o << "null";
                return;
            }
        }
    }

@nlohmann
Copy link
Owner

There are quotes around the array. Therefore, it is treated as string.

@silverist
Copy link
Author

After all, I misunderstood.
I checked the data which do dump() by hex editor, it is not converted.

The reason why it seems to be converted is that a return value which "char* " points seems to lose when a function exit.
I copy the value which "char* " points by memcpy(), and return the destination value.
Then the return value do not lose, and my problem has been resolved.

Thanks all.

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

No branches or pull requests

2 participants