1

数値フィールドの文字列表現にアクセスできる 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 が返されます。

このためだけに、自分で書く必要がないことを本当に望んでいます。

4

4 に答える 4

2

まだご存じない方のために説明すると、http: //www.json.org/ には、さまざまな言語で記述された JSON ライブラリのリストがあり、そのうちの 12 は C で書かれています。

リソースに制約のある組み込みプラットフォームにjsmnを使用しています。JSON 文字列をトークン化するだけなので、そのライブラリから必要なものを取得できますが、有用なことを行うには、その周りにもう少しロジックを構築する必要があります。

同様に、おそらく JSON_checker を調整して、必要なことを行うことができます。

必要な機能が見つからない場合でも、自分で解析するのはそれほど難しくありません。

于 2012-05-22T20:58:56.340 に答える
0

https://github.com/cesanta/frozenを使用できます

あなたが求めているものを正確に示す例が README にあり、ここに短いバージョンがあります:

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)
于 2013-12-28T13:25:28.440 に答える
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;
}
于 2017-04-23T21:44:45.367 に答える
-2

Jansson は素晴らしいライブラリであり、単体テストに基づいて別のライブラリを選択するのは残念です。数値の解析に反対している理由がわかりませんが、説明していただけますか?

コード スニペットに関する限り、構造から数値を取得する際のボイラープレートに少しイライラするかもしれません。json_pack / json_unpack 関数を愛することを学ぶことをお勧めします。次のように、ディクショナリから整数要素を取得できます。

double d;
json_unpack(coord, "{s:f}", "accuracy", &d);

この呼び出しを使用すると、浮動小数点値を表す (json_t *) オブジェクトを操作する必要がなくなります。もちろん、json_unpack() 呼び出しのリターン コードでエラー状態をチェックする必要があります。

于 2012-05-22T21:22:38.310 に答える