为什么Jansson的is_json_object()无法识别我的JSON字符串?

时间:2013-07-07 17:46:36

标签: c++ json jansson

我是C ++的新手,无法弄清楚如何从字符串中删除一些杂项数据,然后将其解析为JSON。

我最终使用了我能找到的记录最多的JSON解析器 - jansson。看起来很棒,虽然我遇到了第一道障碍。

我的程序收到以下格式的字符串:

5::/chat:{"name":"steve","args":[{"connection":"true"}, { "chatbody" : "I am the body" }]}

我已将大括号外的所有内容删除:

std::string str=message;
unsigned pos = str.find("{");
std::string string = str.substr (pos);

离开:

{
    "name": "steve",
    "args": [
        {
            "connection": "true"
        },
        {
            "chatbody": "I am the body"
        }
    ]
}

我陷入第一阶段解析这个问题。我已经将字符串转换为char,然后尝试使用json_loads,但我没有得到任何有用的东西......

整件事看起来像这样:

void processJson(string message)
{
    json_t *root;
    json_error_t error;
    size_t i;

    std::string str=message;
    unsigned pos = str.find("{");
    std::string str3 = str.substr (pos);

    const char * c = str.c_str();

    json_t *data, *sha, *name;

    root = json_loads(c, 0, &error);
    data = json_array_get(root, i);        
    cout << data;

    if(!json_is_object(root))
    {
      fprintf(stderr, "error: commit data %d is not an object\n", i + 1);
    }

}

我需要取出价值,但我只是得到01,02,03 ......

is_json_object只是说:

error: commit data 1068826 is not an object
error: commit data 1068825 is not an object
error: commit data 1068822 is not an object

我做错了什么以及如何正确格式化?最终我需要迭代一个数组,但无法通过它。我确定这只是初学者的错误。

-EDIT-

由于严格的尺寸要求,试图避免使用Boost。

4 个答案:

答案 0 :(得分:4)

您可以随时使用现有的解决方案,例如Boost的属性树,该属性树具有自动解析JSON文件的功能。它实际上就像添加这两个标题一样简单:

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

然后添加这一小段代码,其中jsonfile显然意味着你的文件名。

boost::property_tree::ptree jsontree;
boost::property_tree::read_json(jsonfile, jsontree);

如果您想从JSON树中提取信息,可以这样做,其中type是您要提取的数据的类型,insert.key.path.here是您的密钥的路径,每个父键由句点分隔。

jsonfile.get<type>(insert.key.path.here);

另外,我不相信你在那里的JSON字符串是有效的。你很好地删除了JSON字符串本身的多余部分,但我相信这里有一个问题:

"connection" : true,

您可以在此处检查JSON字符串的有效性:http://jsonformatter.curiousconcept.com/

答案 1 :(得分:4)

对于JSON格式化,我通过C ++搜索了一个漂亮的打印解决方案无济于事。最后,我发现了一些我最终转换为C ++的java代码。尝试以下JSON格式:

std::string formattedJson(char *json)
{
    std::string pretty;

    if (json == NULL || strlen(json) == 0)
    {
        return pretty;
    }

    std::string str     = std::string(json);
    bool        quoted  = false;
    bool        escaped = false;
    std::string INDENT  = "    ";
    int         indent  = 0;
    int         length  = (int) str.length();
    int         i;

    for (i = 0 ; i < length ; i++)
    {
        char ch = str[i];

        switch (ch)
        {
            case '{':
            case '[':
                pretty += ch;

                if (!quoted)
                {
                    pretty += "\n";

                    if (!(str[i+1] == '}' || str[i+1] == ']'))
                    {
                        ++indent;

                        for (int j = 0 ; j < indent ; j++)
                        {
                            pretty += INDENT;
                        }
                    }
                }

                break;

            case '}':
            case ']':
                if (!quoted)
                {
                    if ((i > 0) && (!(str[i-1] == '{' || str[i-1] == '[')))
                    {
                        pretty += "\n";

                        --indent;

                        for (int j = 0 ; j < indent ; j++)
                        {
                            pretty += INDENT;
                        }
                    }
                    else if ((i > 0) && ((str[i-1] == '[' && ch == ']') || (str[i-1] == '{' && ch == '}')))
                    {
                        for (int j = 0 ; j < indent ; j++)
                        {
                            pretty += INDENT;
                        }
                    }
                }

                pretty += ch;

                break;

            case '"':
                pretty += ch;
                escaped = false;

                if (i > 0 && str[i-1] == '\\')
                {
                    escaped = !escaped;
                }

                if (!escaped)
                {
                    quoted = !quoted;
                }

                break;

            case ',':
                pretty += ch;

                if (!quoted)
                {
                    pretty += "\n";

                    for (int j = 0 ; j < indent ; j++)
                    {
                        pretty += INDENT;
                    }
                }

                break;

            case ':':
                pretty += ch;

                if (!quoted)
                {
                    pretty += " ";
                }

                break;

            default:
                pretty += ch;

                break;
        }
    }

    return pretty;
}

答案 2 :(得分:2)

我不熟悉您正在使用的任何JSON库,但这里有一些关于可能出错的建议。

  • size_t i未初始化为任何内容,然后传递到json_array_get
  • json_array_get传递根对象,该对象不是JSON数组,而是JSON对象。在JSON术语中,root["args"]将是数组。

当然,根据你的JSON库的语义,这根本不是问题,但它们对我来说似乎是红旗。

答案 3 :(得分:2)

Casablanca (REST C++ SDK)有一个非常好的JSON解析器,即使您不使用HTTP功能也可以使用它。

您可以将JSON解析器文件解压缩到静态库中,并将其与现有项目链接。要提取的文件是:

src\json\json.cpp
src\json\json_parsing.cpp
src\json\json_serialization.cpp
src\utilities\asyncrt_utils.cpp

include\cpprest\json.h
include\cpprest\xxpublic.h
include\cpprest\basic_types.h
include\cpprest\asyncrt_utils.h

我可以确认这是有效的,因为我最近将它用作我项目的静态库。

我也尝试使用Jansson,但卡萨布兰卡的解析器使用起来更简单,并且支持更好的Unicode。

相关问题