0

I'm parsing a json file with cJSON. Everything is going well. But one of the data elements is a Boolean, and the problem is I don't understand how to use cJSON's functions for reading Boolean types. The data file contains lines like:

"isDaytime": true,

I attempted to use a code block like:

if (cJSON_IsTrue("isDaytime")==0) {
    printf("isDaytime = TRUE\n");
} else {
    printf("isDaytime = FALSE\n");
}

When I try to compile this with gcc, I get the following message:

undefined reference to `cJSON_IsTrue'

I think perhaps cJSON represents it as an int? I don't know. At any rate, does anyone know how I should be calling cJSON_IsTrue() ? Or perhaps I shouldn't be calling cJSON_IsTrue() at all. If not, how should I be checking this type of data element? If it was an int, I'd be done. If it was a char *, I'd be done. I'm just not sure how I'm supposed to test whether it's true or false.

EDIT: According to the documentation for the cJSON library, here:https://github.com/DaveGamble/cJSON

Because the entire library is only one C file and one header file, you can just copy cJSON.h and cJSON.c to your projects source and start using it.

So this was how I was using cJSON. I had just included the two files in my project, and everything was working like a charm. Until I tried using the cJSON_IsTrue() function. I wasn't able to see how to correctly use the function from the documentation, or from the source files. I figured I'd just try to use it, "wrongly", and then correct myself via whatever error messages came up.

I didn't expect to receive the "undefined reference" error message. I looked through the source, and indeed the function was there...

David Collins suggested I needed to link to the cjson library when compiling. I was including the source, so I didn't think that was truly the answer. But okay. So I followed the directions and actually installed the library on my system. And I got the same undefined reference error message.

It turned out that the location where the library installed itself: /usr/local/lib, wasn't being referenced. I copied the installed files to the correct directory for my system and the cJSON_IsTrue() function is now available when I compile with the -lcjson flag.

So how to use it? This is how I used it:

`if ( cJSON_IsTrue(cJSON_GetObjectItem(subitem, "isDayTime")) == 1) {
    /* do something if it's true */
 } else {
    /* do something if it's false */
 }`

This seems to have done the trick. Thanks again @David Collins!

Terry Wendt
  • 28
  • 1
  • 7
  • Even if you fix the API, your parentheses are wrong, you're comparing the string literal's address to `0` (aka `NULL` in this context), it should evaluate to `0`, and then passing `0` to `cJSON_IsTrue`. Presumably, you want something like: `if (cJSON_IsTrue("isDaytime")==0) {`, though I'm not sure where it's supposed to be looking up that string (I don't know the API, but I'd assume there is some struct you'd need to pass representing a parsed object?). – ShadowRanger Jun 22 '18 at 00:58
  • Good point, thanks! The problem is with the call to "cJSON_IsTrue()". I'm just not seeing how to check the value of a Boolean using this API. I'll edit the code block to reflect your comment. – Terry Wendt Jun 22 '18 at 01:02

1 Answers1

4

cJSON_IsTrue() doesn't expect a string literal; it expects a cJSON object.

Suppose json_string is a char * representation of your full JSON object. Then you could try the following.

First of all parse the top-level JSON object.

cJSON *json = CJSON_Parse(json_string);
if (json == NULL) {
    // Handle error and abort if appropriate
}

Then extract your child object.

cJSON *daytime_json = cJSON_GetObjectItemCaseSensitive(json, "isDayTime");
if (cJSON_IsTrue(daytime_json) == 0) {
    // Whatever you need to do next ...
}
// Etc.

Finally, don't forget to de-allocate memory / clean up afterwards.

cJSON_Delete(json);

Compiling / Linking

You mentioned that

When I try to compile this with gcc, I get the following message:
undefined reference to cJSON_IsTrue

You need to link the cjson library when compiling. E.g., if using the gcc compiler, you would use something like

gcc -o json-test json-test.c -lcjson
David Collins
  • 2,852
  • 9
  • 13
  • Okay, I'm going to give this a try. I don't expect it'll work though. I'm already successfully parsing dozens of elements using cJSON from the data file. The problem isn't with compiling cJSON, it's specifically with calling cJSON_IsTrue(). But, I'll try it and let you know. – Terry Wendt Jun 22 '18 at 02:08
  • @TerryWendt: Perhaps you are using an older version of the library. I have tested the latest version from Github (version 1.7.7) and using the `cJSON_IsTrue()` function as I have shown above works fine. – David Collins Jun 22 '18 at 02:27
  • Okay, problem solved. I was just including the cJSON.h and cJSON.c files in my project. I didn't want to add yet another package to the list of packages that had to be installed every time I upgraded my distro... After doing a make/make install I still had to manually copy the *.so files and their links to the correct dir for my system. I'm going to mark your answer as the solution. It wasn't the direct solution, but it did lead me to a way to solve the problem, so... Thank you very much Mr. Collins! – Terry Wendt Jun 22 '18 at 03:16
  • 1
    For future reference, what would be the best way for me to close this question? Should I document the steps I took to solve the problem? If so, should I enter an answer to my own question where I show the steps? I'm not sure because I think my solution may be very linux distro specific. I think you should get the "points" for your answer, but it was more a clue than a solution - and that was good enough for me. But will it be most helpful to people doing a search for a similar problem? Thanks again. – Terry Wendt Jun 22 '18 at 03:36
  • @TerryWendt: Thanks for the feedback. I'm relatively new to SO myself - and am not 100% what the best for you to document your solution is. I guess it would be add another answer yourself (rather than updating your original question - which might just confuse readers). A more experienced SO user might have a different suggestion. – David Collins Jun 22 '18 at 09:30
  • Please specify that cJSON_IsTrue() returns 1 if value is true, else 0 if value is false. – Prashant Shubham Feb 05 '19 at 12:49