1

I have a question with my c code,

What is my code doing ?

  • call to the google API "direction"
  • get a big string "s" which contains json structure
  • write my string s in a file

What is my problem ? I would like to create a automatique structure because my struct is always differents. For example sometimes if have only 200 or 1000 coordinate..

#include <stdio.h>
#include <curl/curl.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#define MAX 300


struct string {
  char *ptr;
  size_t len;
};


void init_string(struct string *s) {
  s->len = 0;
  s->ptr = malloc(s->len+1);
  if (s->ptr == NULL) {
    fprintf(stderr, "malloc() failed\n");
 
  }
  s->ptr[0] = '\0';
}




size_t writefunc(void *ptr, size_t size, size_t nmemb, struct string *s)
{
  size_t new_len = s->len + size*nmemb;
  s->ptr = realloc(s->ptr, new_len+1);
  if (s->ptr == NULL) {
    fprintf(stderr, "realloc() failed\n");
  }
  memcpy(s->ptr+s->len, ptr, size*nmemb);
  s->ptr[new_len] = '\0';
  s->len = new_len;

  return size*nmemb;
}


void getRoad(double doubleLatitude, double doubleLongitude,char *villeDestination[MAX]){
  
  printf("Function : getRoad\n");
  printf("parameters latitude -%f-\n",doubleLatitude);
  printf("parameters longitude -%f-\n",doubleLongitude);
  printf("parameters villeDestination -%s-\n",villeDestination);

  char URL_BASE[MAX],URL;
  

  // CONVERT DOUBLE TO STRING 
  char stringLatitude[50];
  char stringLongitude[50];

  snprintf(stringLatitude, 50, "%f",doubleLatitude);
  snprintf(stringLongitude, 50, "%f",doubleLongitude);


  // WE ARE BUILDING URL URL 
  strcpy (URL_BASE,"https://maps.googleapis.com/maps/api/directions/json?origin=");
  strcat(URL_BASE,stringLatitude);
  strcat(URL_BASE,",");
  strcat(URL_BASE,stringLongitude);
  strcat(URL_BASE,"&destination=");
  strcat(URL_BASE,villeDestination);
  strcat(URL_BASE,"&avoid=highways&mode=bicycling&key=AIzaSyBpj0XoMAHi8naH5k-S8mAr0nexwCQvv2g");

  // OUR URL, YOU CAN TEST IT IN FIREFOX ! 
  printf("%s\n",URL_BASE);

  CURL *curl;
  CURLcode res;

  curl_global_init(CURL_GLOBAL_DEFAULT);

  curl = curl_easy_init();

  if(curl) {

    struct string s;
    init_string(&s);

    curl_easy_setopt(curl, CURLOPT_URL, URL_BASE);

  #ifdef SKIP_PEER_VERIFICATION  
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
  #endif

  #ifdef SKIP_HOSTNAME_VERIFICATION
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
  #endif

    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);

  res = curl_easy_perform(curl);
   
  printf("%s\n", s.ptr);//DEBUG



  // OPEN A FILE AND WRITE DATA 
  FILE *fptr;
  fptr = fopen("dataJson.json", "w");
  if (fptr == NULL) {
    printf("Error!");
    exit(1);
  }
  fprintf(fptr, "%s", s.ptr);
  fclose(fptr);


  //printf("%s\n",curl_easy_perform(curl));//DEBUG
  if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",curl_easy_strerror(res));
    curl_easy_cleanup(curl);
  }
  curl_global_cleanup();
}

  /*
   * Exemple type adepart avec des coordonnées 
   * 
   * origin 50.642782,2.833267
   * destination paris
   *
   * https://maps.googleapis.com/maps/api/directions/json?origin=50.642782,2.833267&destination=paris&avoid=highways&mode=bicycling&key=AIzaSyBpj0XoMAHi8naH5k-S8mAr0nexwCQvv2g
  */


int main(void){
  
  //getCoordinate();
  // Coord depart - ville destination
  getRoad(50.642782,2.833267,"nieppe");

  return 0;
}

enter image description here

Armali
  • 18,255
  • 14
  • 57
  • 171
  • `char *villeDestination[MAX]` in the parameter list of `getRoad` is wrong - drop `*` or `[MAX]`. – Armali Feb 27 '21 at 10:58
  • 1
    I don't understand your problem. You already have an _automatique structure_ `struct string` which stores a string of any length, and its implementation is correct. – Armali Feb 27 '21 at 11:12
  • Hello, I will explain my problem, I have a big string and this string contain my big structure json and I would like to access data in my string – Gautier Essam Mar 01 '21 at 11:43
  • You didn't explain your problem. Where's the problem in accessing data in a string? – Armali Mar 01 '21 at 18:25
  • Yes sorry , thx you for you answer, I don't no how to access data in my big string like this { "geocoded_waypoints" : [ { "geocoder_status" : "OK", "place_id" : "ChIJbRcWwsZMFkcRcXvXdyuxSyw", "types" : [ "street_address" ] }, { "geocoder_status" : "OK", "place_id" : "ChIJD7fiBh9u5kcRYJSMaMOCCwQ", "types" : [ "locality", "political" ] } ], "routes" : [ { "bounds" : { "northeast" : { "lat" : 52.2236303, "lng" : 20.203097 } – Gautier Essam Mar 02 '21 at 11:33

1 Answers1

0

I don't no how to access data in my big string like this { "geocoded_waypoints" : [ { "geocoder_status" : "OK", "place_id" : "ChIJbRcWwsZMFkcRcXvXdyuxSyw", "types" : [ "street_address" ] }, { "geocoder_status" : "OK", "place_id" : "ChIJD7fiBh9u5kcRYJSMaMOCCwQ", "types" : [ "locality", "political" ] } ], "routes" : [ { "bounds" : { "northeast" : { "lat" : 52.2236303, "lng" : 20.203097 }

You seem to want a JSON implementation to parse the JSON formatted string. Perhaps you already have JSON-C on your system; in this case you just have to link your program with -ljson-c and you can use for example these calls:

#include <json-c/json.h>
...
    struct json_object *obj = json_tokener_parse(s.ptr);
    if (!obj) { fputs("json_tokener_parse failed\n", stderr); return; }

    struct json_object *way = json_object_object_get(obj, "geocoded_waypoints");
    if (!way) { fputs("no geocoded_waypoints\n", stderr); return; }

    size_t len = json_object_array_length(way);
    printf("There are %zd waypoints.\n", len);
    for (size_t idx = 0; idx < len; ++idx)
    {   printf("waypoint %zd:\n", idx);
        struct json_object *point = json_object_array_get_idx(way, idx);
        printf("geocoder_status is %s\n", json_object_get_string(json_object_object_get(point, "geocoder_status")));
        printf("place_id is %s\n",        json_object_get_string(json_object_object_get(point, "place_id")));
        printf("types is %s\n",           json_object_get_string(json_object_object_get(point, "types")));
    }

    struct json_object *routes = json_object_object_get(obj, "routes");
    if (!routes) { fputs("no routes\n", stderr); return; }

    size_t routeslen = json_object_array_length(routes);
    printf("There are %zd routes.\n", routeslen);
    for (size_t idx = 0; idx < routeslen; ++idx)
    {   printf("route %zd:\n", idx);
        struct json_object *route = json_object_array_get_idx(routes, idx);
        printf("bounds is %s\n", json_object_get_string(json_object_object_get(route, "bounds")));
    }
Armali
  • 18,255
  • 14
  • 57
  • 171
  • 1
    Oh yes , I will check this librairie thank you, for your help, and your time spent ! – Gautier Essam Mar 03 '21 at 19:57
  • Please add additional info that you want to provide, like the picture, to your question post rather than to this answer. I moved it. – Armali Mar 03 '21 at 21:19
  • Yes, you need nested loops for nested arrays, as for the array `legs`. I could expand the example, if you want. (Of course you wouldn't need a loop if you were sure that there's only one element in the array, or if you wanted to access only the first element.) – Armali Mar 03 '21 at 21:22
  • normally I will succeed by myself, I woul pratice ;) last one question I have many object how to access to the object ? thank you very much – Gautier Essam Mar 03 '21 at 21:28
  • For example now I have differents structure like "struct json_object *way" or "struct json_object *routes" , but I would like to browse the informations in the object ? I don't now if I'm clear – Gautier Essam Mar 03 '21 at 21:42
  • Regarding _I have many object how to access to the object_: The topmost object is returned by `json_tokener_parse()`. Inner Objects are returned by `json_object_object_get()` or `json_object_array_get_idx()`. This can recursively be applied to objects further in the tree, as in the example done with `obj` -> `way` from geocoded_waypoints -> `point` from an element of the array -> strings from geocoder_status, place_id, types. – Armali Mar 03 '21 at 21:44
  • I'm not sure what you mean by _browse_. – Armali Mar 03 '21 at 21:48
  • okay I do a recursive code ? In my JSON I have bounds" : { "northeast" : { "lat" : 52.2236303, "lng" : 20.203097}. Now I have this in my object obj , how to access "lat" for example with obj->routes->bouds->northeast->lat ? – Gautier Essam Mar 03 '21 at 21:51
  • The steps up to bounds are in the example. To go from bounds to northeast, the next step would be e. g. `struct json_object *bounds = json_object_object_get(route, "bounds"); struct json_object *ne = json_object_object_get(bounds, "northeast");`. – Armali Mar 03 '21 at 22:04