parse json arrays using cJSON library - c

First off, this is a very broad question, and it might come across as me asking for the community to write my code for me. That is not my intent, but I am so lost, I don't know how to give enough information.
I am attempting to use the cJSON library, written by Dave Gamble,
I found this is very useful to use for my embedded device for JSON parse and composing.
to read in the following JSON array
{
"name": "Jack",
"types":[23,56,78],
"format": {
"type": "rect",
"width": 1920, }
}
.. and parsing the getting the object worked with this method
cJSON *format = cJSON_GetObjectItem(json,"format");
int framerate = cJSON_GetObjectItem(format,"width")->valueint;
but I am not able to parse the key "name" and object simple key value ,
I tried this
cJSON *array = cJSON_GetArrayItem(json,"types");
int value = cJSON_GetArrayItem(format1,1)->valueint;
but did not work, how to parse the array object and simple key value..

Your json is just fine. You can iterate through array of values in cJSON:
cJSON * array = cJSON_GetObjectItem(json, "types");
for (i = 0 ; i < cJSON_GetArraySize(array) ; i++)
{
printf("%d ",cJSON_GetArrayItem(array, i)->valueint);
}
will print
23 56 78

I think JSON element should respect key:value format.
{
"name": "Jack",
"types":[{"type" : 23}, {"type" : 56}, {"type":78}],
"format": {
"type": "rect",
"width": 1920, }
}

Related

flutter get json array

Hi I have this JSON as a string as a response for an API call
{
"friends": {
"data": [],
"summary": {
"total_count": 42
}
},
"id": "111111111111111"
}
I want to get friends.data and friends.summary.total_count.
Something like :
for (int i = 0 ; i < friends.summary.total_count ; i++)
{
myAmazingArray.pushback(friends.data[i]);
}
I think that total_count is the number of contents in the array.
I also know that in order to get the "id" I have to do : json['name']
You need to use jsonDecode from dart:convert. Actually you don't even need to use the total_count value at all, if the length in data is the same. You can simply use:
import 'dart:convert';
final Map<String, dynamic> dataMap = jsonDecode(json);
final List<dynamic> friendsData = dataMap['friends']['data'];
for(dynamic friend in friendsData) myAmazingArray.pushback(friend);
I don't know what kind of content is contained in data, so I suggest you to find out the runtime type (e.g. String, Map etc.) and exchange the word 'dynamic' in my code above to improve the code quality.
If you wanted to do it with total_count:
final int total_count = dataMap['friends']['summary']['total_count'];
for(int i=0; i<total_count; i++)
myAmazingArray.pushback(friendsData[i]);

Extract different set of keys for different nesting level of json

I have the following JSON object, from which I need to retrieve values of certain keys.
For example, in outer JSON object, I need only "timestamp" and "type", next from a nested "meta" object I need only "version", and from nested "payload" I want fields "reason", "type" and "condition" from its nested object "data"
{
"timestamp": "1568961295627",
"type": "test",
"namespace": "internal",
"meta": {
"version": "2.0-test",
"id": "123"
},
"payload": {
"data": {
"reason": "user_request",
"type": "asd",
"condition": "bad"
},
"contentType": "application/json"
}
}
I wrote a function to retrieve such data:
void log_values(json_t *data) {
json_t *obj = NULL;
json_t *nested = NULL;
syslog(LOG_INFO, "%s: ", json_string_value(json_object_get(data, "timestamp")));
syslog(LOG_INFO, "%s: ", json_string_value(json_object_get(data, "type")));
obj = json_object_get(data, "meta");
syslog(LOG_INFO, "%s: ", json_string_value(json_object_get(obj, "version")));
obj = json_object_get(data, "payload");
nested = json_object_get(obj, "data");
syslog(LOG_INFO, "%s: ", json_string_value(json_object_get(nested, "reson")));
syslog(LOG_INFO, "%s: ", json_string_value(json_object_get(nested, "type")));
syslog(LOG_INFO, "%s: ", json_string_value(json_object_get(nested, "condition")));
}
However, the code looks repetitive and I'm wondering if there is any way to generalize it?
The first thing which came to mind is to create a jagged array of pointers to keys needed for each stage, and then walk through the array and retrieve only certain keys on certain nesting level, for example:
char *nested0 = {"timestamp", "type"};
char *nested1 = {"anomaly", "version"};
char *nested2 = {"reason", "type", "condition"};
char *(*keys[])[] = { &nested0, &nested1, &nested2 }
But, this solution does not solve problem regarding where to store key names, which point to nested JSONs (e.g "meta, payload, data").
So, the question is: How to generalize the aforementioned code and what data structure should I use to store names of keys holding a json object and keys for which I need to get values.
Take a look at jsmn, it should fit your needs : https://github.com/zserge/jsmn
exemple of what you could do with jsmn :
[user#machine ~]$ ./json_parser_with_keys test.json timestamp type meta/version
timestamp=1568961295627
type=test
meta/version=2.0-test
[user#machine ~]$ ./json_parser_full test.json
/timestamp=1568961295627
/type=test
/namespace=internal
/meta/version=2.0-test
/meta/id=123
/payload/data/reason=user_request
/payload/data/type=asd
/payload/data/condition=bad
/payload/contentType=application/json
[user#machine ~]$

how to parse golang json array having random hash value in field name [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I'm trying to parse JSON from API in golang code.
Of passed with true option argument it gives different additional info and with false different output.
I have covered that in the following golang play link:
https://play.golang.org/p/-JffO4AS01N
I need to parse the value of variable mtJson.
Used the Json to Go (https://mholt.github.io/json-to-go/) converted to get help in creating the struct type for this. But it was giving following struct type for the json example:
{
"result": {
"99c4d91acc2486955c98015fbbdf06239b983c9d93d5069c39d040702af88738": {
"size": 845,
"fee": 0.000144,
"time": 1547444481,
"height": 1183405,
"startingpriority": 89509.20245398773,
"currentpriority": 89509.20245398773,
"depends": []
},
"73f582cf419f8b1cd6a87f81e0e9a4e783add27c2be083361e8eb4a3bac0134e": {
"size": 1635,
"fee": 0.000312,
"time": 1547444435,
"height": 1183405,
"startingpriority": 341863.3540372671,
"currentpriority": 341863.3540372671,
"depends": []
}
},
"error": null,
"id": "curltest"
}
type AutoGenerated struct {
Result struct {
Nine9C4D91Acc2486955C98015Fbbdf06239B983C9D93D5069C39D040702Af88738 struct {
Size int `json:"size"`
Fee float64 `json:"fee"`
Time int `json:"time"`
Height int `json:"height"`
Startingpriority float64 `json:"startingpriority"`
Currentpriority float64 `json:"currentpriority"`
Depends []interface{} `json:"depends"`
} `json:"99c4d91acc2486955c98015fbbdf06239b983c9d93d5069c39d040702af88738"`
Seven3F582Cf419F8B1Cd6A87F81E0E9A4E783Add27C2Be083361E8Eb4A3Bac0134E struct {
Size int `json:"size"`
Fee float64 `json:"fee"`
Time int `json:"time"`
Height int `json:"height"`
Startingpriority float64 `json:"startingpriority"`
Currentpriority float64 `json:"currentpriority"`
Depends []interface{} `json:"depends"`
} `json:"73f582cf419f8b1cd6a87f81e0e9a4e783add27c2be083361e8eb4a3bac0134e"`
} `json:"result"`
Error interface{} `json:"error"`
ID string `json:"id"`
}
This doesn't seem right.
The value of the string hash key will be always different not determined, so can not just set that as is in struct.
I'm feeling confused on how to parse the JSON so that I can finally get the values like this:
fmt.Println(mt.Result.("99c4d91acc2486955c98015fbbdf06239b983c9d93d5069c39d040702af88738").Size)
fmt.Println(mt.Result.("99c4d91acc2486955c98015fbbdf06239b983c9d93d5069c39d040702af88738").Fee)
Please help
I have covered that in the following golang play link:
https://play.golang.org/p/-JffO4AS01N
I have covered that in the following golang play link:
https://play.golang.org/p/-JffO4AS01N
Expected:
fmt.Println(mt.Result.("99c4d91acc2486955c98015fbbdf06239b983c9d93d5069c39d040702af88738").Size)
845
fmt.Println(mt.Result.("99c4d91acc2486955c98015fbbdf06239b983c9d93d5069c39d040702af88738").Fee)
0.000144
Actual Result: {{0 0 0 0 0 0 []}}
Since the keys are not known, you have to resort to a dynamic data structure.
Define the single element like:
type Element struct {
Size int `json:"size"`
Fee float64 `json:"fee"`
Time int `json:"time"`
Height int `json:"height"`
Startingpriority float64 `json:"startingpriority"`
Currentpriority float64 `json:"currentpriority"`
Depends []interface{} `json:"depends"`
}
Then parse your json to a map[string]Element like so:
result := make(map[string]Element)
json.Unmarshal(jsonBytes, &result)

Correct structure for json unmarshal

I can't figure out how to build a structure for this json object in golang:
{
"response": [1702487, {
"uid": 150261846,
"first_name": "Олег",
"last_name": "Брейн"
}, {
"uid": 53260546,
"first_name": "Олег",
"last_name": "Лобацевич"
}
]
}
As you can see there is no keys names for array and for count too.
Would be glad if you can help
In this situation you'll have to punt and use interface{} somewhere, for example:
package main
import (
"fmt"
"encoding/json"
)
type JsObject struct {
Response []interface{}
}
func main() {
bs := []byte(`{"response":[1702487,{"uid":150261846,"first_name":"Олег","last_name":"Брейн"},{"uid":53260546,"first_name":"Олег","last_name":"Лобацевич"}]}`)
var jso JsObject
json.Unmarshal(bs, &jso)
fmt.Printf("%+v\n", jso)
}
Json to go is quite handy for this sort of thing:
https://mholt.github.io/json-to-go/
If you can remove the spurious 1702487 which makes this a heterogenous list, you should be able to parse it easily into a proper structure, otherwise you might be stuck using interface:
https://play.golang.org/p/w7ebLTuOj9
Presumably you want an array of structs like this:
type Person struct {
UID int `json:"uid"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
}
not sure what 1702487 is but if uid of request, it doesn't really belong in the array.
type AutoGenerated struct {
Response []interface{} `json:"response"`
}

Reading complicated format string with fscanf

I have a kindof complicated file format:
{
"color": [
45,
200,
34
],
"docnum": 5183,
"form": "avoir",
"graph": "jdm.N.flat",
"id": 0,
"lang": "fr",
"neighbors": 17,
"pos": "N",
"pzero": true,
"rank": 1,
"score": 0.0028284271,
"type": 1
},
{
"color": [
45,
200,
34
],
"docnum": 22809,
"form": "argent",
"graph": "jdm.N.flat",
"id": 1,
"lang": "fr",
"neighbors": 65,
"pos": "N",
"pzero": false,
"rank": 2,
"score": 0.0028284271,
"type": 1
},
This kind of list goes on, for hundreds of entries. I would like to read in the variable numbers, and a string (docnum, form, id, neighbors, rank, score) so i created a format string for this kind of input:
main(){
FILE* in=fopen("fr.N.bien2","r");
int maxwords=100;
int maxstringlen=100;
char* nodes=malloc(sizeof(char)*maxstringlen*maxwords);
if(!nodes){printf("Nodes couldn't be allocated!\n");}
int i=0;
int* IDs=malloc(sizeof(int)*3*maxwords);
int docnum,nei,rank;
float score;
char* pzero;
while(fscanf(in," { \"color\": [ 45, 200, 34 ], \"docnum\": %i, \"form\": %s \"graph\": \"jdm.N.flat\", \"id\": %i , \"lang\": \"fr\", \"neighbors\": %i , \"pos\": \"N\", \"pzero\": false, \"rank\": %i , \"score\": %f , \"type\" :1 },",&docnum,&nodes[i],&IDs[i],&nei,pzero,&rank,&score))
{
printf("node:%s,ID=%i\n",&nodes[i],IDs[i]);
i++;
}
}
It looks complicated, but it seems to be working, because I get the first instance right. The output is:
>>node:"avoir",,ID=0
However, output stops at that, even though the format is exactly repeating in the file (as you can see in the sample).
Am I missing something important here?
Is there an easier way to read in this kind of data from such a file?
And this complicated format is JSON
As the comments suggest, look for a library instead (they can be found following the previous link) there's many libraries and for different languages as well.
In fact, your question might be already answered here

Resources