/* * compilation: * gcc this_file.c -lcurl -ljansson */ #include #include #include #include #define BUFFER_SIZE (256 * 1024) /* 256 KB */ struct write_result { char *data; int pos; }; static size_t write_response(void *ptr, size_t size, size_t nmemb, void *stream) { struct write_result *result = (struct write_result *)stream; if(result->pos + size * nmemb >= BUFFER_SIZE - 1) { fprintf(stderr, "error: too small buffer\n"); return 0; } memcpy(result->data + result->pos, ptr, size * nmemb); result->pos += size * nmemb; return size * nmemb; } static char *request(const char *url) { CURL *curl = NULL; CURLcode status; struct curl_slist *headers = NULL; char *data = NULL; long code; curl_global_init(CURL_GLOBAL_ALL); curl = curl_easy_init(); if(!curl) goto error; data = malloc(BUFFER_SIZE); if(!data) goto error; struct write_result write_result = { .data = data, .pos = 0 }; curl_easy_setopt(curl, CURLOPT_URL, url); headers = curl_slist_append(headers, "User-Agent: Jansson-Tutorial"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_response); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &write_result); status = curl_easy_perform(curl); if(status != 0) { fprintf(stderr, "error: unable to request data from %s:\n", url); fprintf(stderr, "%s\n", curl_easy_strerror(status)); goto error; } curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code); if(code != 200) { fprintf(stderr, "error: server responded with code %ld\n", code); goto error; } curl_easy_cleanup(curl); curl_slist_free_all(headers); curl_global_cleanup(); /* zero-terminate the result */ data[write_result.pos] = '\0'; return data; error: if(data) free(data); if(curl) curl_easy_cleanup(curl); if(headers) curl_slist_free_all(headers); curl_global_cleanup(); return NULL; } int main(int argc, char *argv[]) { size_t i, j; char *text; char *url = "https://api.hh.ru/industries"; char *api_name = "industries"; json_t *root; json_error_t error; text = request(url); if(!text) return 1; root = json_loads(text, 0, &error); free(text); if(!root) { fprintf(stderr, "error: on line %d: %s\n", error.line, error.text); return 1; } if(!json_is_array(root)) { fprintf(stderr, "error: root is not an array\n"); json_decref(root); return 1; } for(i = 0; i < json_array_size(root); i++) { json_t *item_0, *item_1, *name_0, *name_1; item_0 = json_array_get(root, i); if(!json_is_object(item_0)) { fprintf(stderr, "error: list item %d is not an object\n", (int)(i + 1)); json_decref(root); return 1; } name_0 = json_object_get(item_0, "name"); if(!json_is_string(name_0)) { fprintf(stderr, "error: list %d: name_0 is not a string\n", (int)(i + 1)); return 1; } printf("%s\n", json_string_value(name_0)); item_1 = json_object_get(item_0, api_name); if(!json_is_array(item_1)) { fprintf(stderr, "error: list %d: item_1 is not an array\n", (int)(i + 1)); json_decref(root); return 1; } for(j = 0; j < json_array_size(item_1); j++) { json_t *o = json_array_get(item_1, j); if(!json_is_object(o)) { fprintf(stderr, "error: list %d: o is not a object\n", (int)(i + 1)); return 1; } name_1 = json_object_get(o, "name"); if(!json_is_string(name_1)) { fprintf(stderr, "error: list %d: name_1 is not a string\n", (int)(i + 1)); return 1; } printf(" %s\n", json_string_value(name_1)); } } json_decref(root); return 0; }