任何人都知道基于C的JSON解析器允许我访问数字字段的字符串表示吗?我的意思是:
json_t * dist = json_object_get(coord, "accuracy");
snprintf(dataOut->distance, MAX_COORD_LEN, "%f", json_number_value(dist));
编写单元测试很愚蠢。我更愿意简单地调用json_string_value(dist)
并获得该数字的字符串。我更愿意进一步说它没有把这个字符串转换为数字。这样,当我为我的例程提供一个包含“54.6045”的测试字符串时,我得到“54.6045”,而不是一些填充或舍入的值...而且我不需要解析数字因为我永远不会去将它作为一个使用。
据我所知,没有这样的事情......在我看来是非常愚蠢的。上面的例子来自Jansson,使用字符串值函数返回null。
我真的不想因为这个而写自己的。
答案 0 :(得分:2)
如果您还不知道这一点,http://www.json.org/会维护一个用各种语言编写的JSON库列表,其中包括12个用C语言编写的。
我正在使用jsmn作为资源受限的嵌入式平台。它所做的只是标记化JSON字符串,因此您可以从该库中获得所需的内容,但是您需要在其周围构建更多的逻辑来执行任何有用的操作。
同样,你可以调整JSON_checker来做你想做的事。
如果找不到符合你想要的东西,那就自己解析并不难。
答案 1 :(得分:0)
您可以使用https://github.com/cesanta/frozen
自述文件中有一个示例可以准确显示您的要求,这是一个简短的版本:
static const char *str = " { foo: { bar: [ 80, 443 ], baz: 1.2e-21 } } ";
struct json_token tokens[50];
int size = sizeof(tokens) / sizeof(tokens[0]);
const struct json_token *tok = NULL;
parse_json(str, strlen(str), tokens, size);
tok = find_json_token(tokens, "foo.bar[1]");
printf("My number is: [%.*s]\n", tok->len, tok->ptr)
答案 2 :(得分:0)
Tiny-json是一个C解析器,它允许您以最简单的方式访问数字字段中的字符串表示。只需要一个JSON属性,它就会返回一个以null结尾的指针。 https://github.com/rafagafe/tiny-json
#include <stdio.h>
#include "tiny-json.h"
int main( int argc, char** argv ) {
char str[] = "{\"accuracy\":654,\"real\":2.54e-3}";
// In the example only 3 is needed. For root and two fields.
json_t mem[ 3 ];
json_t const* root = json_create( str, mem, sizeof mem / sizeof *mem );
if ( !root ) {
fputs( "Cannot create a JSON.\n", stderr );
return 1;
}
{ // You can get the primitive values as text format:
char const* accuracy = json_getPropertyValue( root, "accuracy" );
if ( !accuracy ) {
fputs( "The filed 'accuracy' is not found.\n", stderr );
return 1;
}
printf( "The accuracy value: %s\n", accuracy );
char const* real = json_getPropertyValue( root, "real" );
if ( !real ) {
fputs( "The filed 'real' is not found.\n", stderr );
return 1;
}
printf( "The real value: %s\n", real );
}
{ // You can check the type of a field and get its value in binary format:
json_t const* accuracy = json_getProperty( root, "accuracy" );
if ( !accuracy ) {
fputs( "The filed 'accuracy' is not found.\n", stderr );
return 1;
}
if( json_getType( accuracy ) != JSON_INTEGER ) {
fputs( "The filed 'accuracy' is not an integer.\n", stderr );
return 1;
}
// Get the value in binary format:
long long accuracyVal = json_getInteger( accuracy );
printf( "The accuracy value: %lld\n", accuracyVal );
// Get the value in text format:
char const* accuracyTxt = json_getValue( accuracy );
printf( "The accuracy value: %s\n", accuracyTxt );
json_t const* real = json_getProperty( root, "real" );
if ( !accuracy ) {
fputs( "The filed 'real' is not found.\n", stderr );
return 1;
}
if( json_getType( real ) != JSON_REAL ) {
fputs( "The filed 'real' is not a real.\n", stderr );
return 1;
}
// Get the value in binary format:
double realVal = json_getReal( real );
printf( "The real value: %f\n", realVal );
// Get the value in text format:
char const* realTxt = json_getValue( real );
printf( "The real value: %s\n", realTxt );
}
return 0;
}
答案 3 :(得分:-2)
Jansson是一个很棒的图书馆,选择另一个基于单元测试的图书馆会很遗憾。我不确定你为什么反对解析数值 - 你能解释一下吗?
就您的代码片段而言,您可能会对从结构中检索数值所涉及的样板文件感到有些恼火。我建议你学会喜欢json_pack / json_unpack函数。您可以按如下方式从字典中检索整数元素:
double d;
json_unpack(coord, "{s:f}", "accuracy", &d);
使用此调用,您不必使用表示浮点值的(json_t *)对象。当然,您应该检查json_unpack()调用的错误条件的返回代码。