C++ 为什么 Jansson 的 is_json_object() 无法识别我的 JSON 字符串?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17514611/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is Jansson's is_json_object() failing to recognize my JSON string?
提问by simonmorley
I am new to C++ and cannot figure out how to strip some miscellaneous data from a string and then parse it as JSON.
我是 C++ 新手,无法弄清楚如何从字符串中剥离一些杂项数据,然后将其解析为 JSON。
I've ended up using the most documented JSON parser I could find - jansson. It seems excellent, although I'm stuck at the first hurdle.
我最终使用了我能找到的记录最多的 JSON 解析器 - jansson。看起来很棒,虽然我被困在第一个障碍。
My program receives a string in the following format:
我的程序接收以下格式的字符串:
5::/chat:{"name":"steve","args":[{"connection":"true"}, { "chatbody" : "I am the body" }]}
I've stripped everything outside the curly brackets with:
我已经剥离了大括号外的所有内容:
std::string str=message;
unsigned pos = str.find("{");
std::string string = str.substr (pos);
That leaves:
那留下:
{
"name": "steve",
"args": [
{
"connection": "true"
},
{
"chatbody": "I am the body"
}
]
}
I'm stuck at stage one parsing this. I have converted the string to a char and then tried to use json_loads, but I don't get anything useful out...
我被困在解析这个的第一阶段。我已将字符串转换为字符,然后尝试使用 json_loads,但我没有得到任何有用的东西...
The whole thing looks like this:
整个事情看起来像这样:
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);
}
}
I need to get the values out, but I just get 01, 02, 03....
我需要取出值,但我只得到 01、02、03....
is_json_object just says:
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
What am I doing wrong and how can I properly format this? Ultimately I'll need to iterate over an array but cannot get past this. I'm sure this is just a beginner's mistake.
我做错了什么,如何正确格式化?最终我需要遍历一个数组,但不能通过这个。我敢肯定这只是初学者的错误。
-EDIT-
-编辑-
Trying to avoid using Boost because of a strict size requirement.
由于严格的大小要求,试图避免使用 Boost。
回答by Kein Mitleid
You could always use an existing solution like Boost's property tree, which has a function for automatically parsing JSON files. It's literally as easy as adding these two headers:
您始终可以使用现有的解决方案,例如 Boost 的属性树,它具有自动解析 JSON 文件的功能。从字面上看,就像添加这两个标题一样简单:
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
And then adding this small snippet of code in, where jsonfile obviously means your filename.
然后在其中添加这一小段代码,其中 jsonfile 显然表示您的文件名。
boost::property_tree::ptree jsontree;
boost::property_tree::read_json(jsonfile, jsontree);
If you ever want to extract information from your JSON tree, you can do it like this, where type is the type of the data you want you extract, and insert.key.path.here is the path to your key, with each parent key separated by periods.
如果你想从你的 JSON 树中提取信息,你可以这样做,其中 type 是你想要提取的数据的类型,insert.key.path.here 是你的密钥的路径,每个父级以句点分隔的键。
jsonfile.get<type>(insert.key.path.here);
In addition, I don't believe the JSON string you have there is valid. You did good removing the excess around the JSON string itself, but I believe there's a problem here:
此外,我不相信您拥有的 JSON 字符串有效。你很好地去除了 JSON 字符串本身周围的多余部分,但我相信这里有一个问题:
"connection" : true,
You can check the validity of your JSON string here: http://jsonformatter.curiousconcept.com/
您可以在此处检查 JSON 字符串的有效性:http: //jsonformatter.curiousconcept.com/
回答by Kona Kid
For JSON formatting, I've searched for a pretty print solution via C++ to no avail. Finally, I found some java code which I eventually converted to C++. Try the following for JSON formatting:
对于 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;
}
回答by David Adrian
I'm not familiar with whatever JSON library you're using, but here's a few suggestions about what might be wrong.
我不熟悉您使用的任何 JSON 库,但这里有一些关于可能出错的建议。
size_t i
is not initialized to anything, and is then passed intojson_array_get
.json_array_get
is passed the root object, which is not a JSON array, but a JSON object. In JSON terminology,root["args"]
would be the array.
size_t i
未初始化为任何内容,然后传入json_array_get
.json_array_get
传递的是根对象,它不是一个 JSON 数组,而是一个 JSON 对象。在 JSON 术语中,root["args"]
将是数组。
Of course, depending on the semantics of your JSON library, neither of this might be issues at all, but they seem like red flags to me.
当然,根据您的 JSON 库的语义,这两者都可能根本不是问题,但对我来说它们似乎是危险信号。
回答by Bogdan
Casablanca (REST C++ SDK)has a pretty nice JSON parser which you can use even if you don't use the HTTP functionality.
Casablanca (REST C++ SDK)有一个非常好的 JSON 解析器,即使您不使用 HTTP 功能也可以使用它。
You can extract the JSON parser files into a static library and link it with your existing project. The files to extract are:
您可以将 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
I can confirm this works as I've used it recently as a static library for my projects.
我可以确认这是有效的,因为我最近将它用作我项目的静态库。
I also tried to use Jansson but the parser in Casablanca simply feels easier to use and has better Unicode support.
我也尝试过使用 Jansson,但是 Casablanca 中的解析器感觉更容易使用并且具有更好的 Unicode 支持。