Ideally, you would use a proper recursive JSON parser, like the one
suggested in prakharsingh95's answer. However, if youcode speed and size
knoware critical considerations, and if the format of the response is always the same, and you know the
string "action_status" is not going to appear as a value of some
other fieldnarrowly constrained, then you can use simplerbuild a fast special-purpose parser.
Here is a simple example. It assumes the response has been stored in the
response char array:
static const char key[] = "\"action_status\"";
const char *p, *q;
char action_status[16];
for (p = response; ; p = q) {
p = strstr(p, key); // find key
if (!p) break; // not found
p = strchr(p, ':'); // find ':' between key and value
p = strchr(p, '"'); // find opening quotes for the value
q = strchr(p+1, '"'); // find closing quotes
// Report finding.
strncpy(action_status, p+1, q-p-1);
action_status[q-p-1] = '\0';
Serial.print("Found action status: ");
Serial.println(action_status);
}
Of course, in production code you would check that every strchr call
returns a non-NULL pointer. And you would check that the status you
found fits in your buffer.
Edit about the pros and cons of this method:
Compared to a proper JSON parser, this approach will give you smaller and faster code, the drawback is it being more fragile. For example, this will not detect a corrupted JSON, and it will return garbage if the action_status happens to be a number instead of a string, or is a string with embedded double quotes, or if the string "action_status" appears as a value of some other field... A full JSON parser should correctly handle all these cases.
On a non-embedded computer, a proper JSON parser would probably be the only appropriate answer. On a constrained microcontroller environment, you sometimes have to make trade-offs. In this particular instance, the “best” answer depends on how much you weight speed and size vs. robustness against unexpected input.