Some error while performing string operations

半腔热情 提交于 2019-12-25 17:46:21

问题


Below is my code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <json/json.h>
#include <curl/curl.h>
#include <sys/types.h>
#include <db.h>

#define  DATABASE "access.db" 


int db_json(char *val, char *key1);
void json_parse(char* str);

struct MemoryStruct {
  char *memory;
  size_t size;
};

char *begin = "<return>";
char *end = "</return>";
char *token;
char *json;
char *newstr = NULL;
char *str = NULL;
char *str1 = NULL;
char *str2 = NULL;
char *str3 = NULL;
char *finalstr = NULL;
char *str4 = NULL;

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;

  mem->memory = realloc(mem->memory, mem->size + realsize + 1);
  if (mem->memory == NULL) {
    /* out of memory! */ 
    printf("not enough memory (realloc returned NULL)\n");
    exit(EXIT_FAILURE);
  }

  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;

  return realsize;
}

char *replace(const char *s, const char *old, const char *new)
{
char *ret;
int i, count = 0;
size_t newlen = strlen(new);
size_t oldlen = strlen(old);

for (i = 0; s[i] != '\0'; i++) {
if (strstr(&s[i], old) == &s[i]) {
count++;
i += oldlen - 1;
}
}

ret = malloc(i + count * (newlen - oldlen));
if (ret == NULL)
exit(EXIT_FAILURE);

i = 0;
while (*s) {
if (strstr(s, old) == s) {
strcpy(&ret[i], new);
i += newlen;
s += oldlen;
} else
ret[i++] = *s++;
}
ret[i] = '\0';

return ret;
}



void json_parse(char *str) {

json_object * jobj = json_tokener_parse(str);


 enum json_type type;
 json_object_object_foreach(jobj, key, val) {
 type = json_object_get_type(val);

 switch (type) {
 case json_type_string: printf("type: json_type_string, ");
 printf("value: %s\n", json_object_get_string(val));
 printf("%s\n",key);

 db_json(json_object_get_string(val), key);  

 break;
 }
 }
 }

 int db_json(char *val, char *key1) {

typedef struct {

char data1[500];

} pearson_record;

pearson_record s;


int i =0;
 DB *dbp;
    DBT key, data;
    int ret, t_ret;
    int recno;



    if ((ret = db_create(&dbp, NULL, 0)) != 0) {
        fprintf(stderr, "db_create: %s\n", db_strerror(ret));
        exit (1);
    }

    // if ((ret = dbp->set_flags(dbp, DB_RECNUM)) != 0) {
        // fprintf(stderr, "db_create: %s\n", db_strerror(ret));
        // exit (1);
    // }

    if ((ret = dbp->open(dbp,
        NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
        dbp->err(dbp, ret, "%s", DATABASE);
        goto err;
    }
printf("data: %s\n",val);
    strncpy(s.data1, val, strlen(val)+1);


    //printf("chk %\n",jvalue);

    recno = 10;

    memset(&key, 0, sizeof(key));
    memset(&data, 0, sizeof(data));
    //memset(&s, 0, sizeof(struct pearson_record));
    key.data = key1;
    key.size = sizeof(key1);
    data.data = &s;
    data.size = sizeof(s);


     if ((ret = dbp->put(dbp, NULL, &key,&data,0)) == 0)
    printf("db: %s: key stored.\n", (char *)key.data);

    else
    {
        dbp->err(dbp, ret, "DB->put");
        goto err;
    }

    pearson_record *ppr;
         if ((ret = dbp->get(dbp, NULL, &key, &data, 0)) == 0) {

    ppr = (pearson_record *) data.data;

    printf("db: %s: key retrieved: data was %s %d\n",
            (char *)key.data, ppr->data1, data.size);
    }
    else {
        dbp->err(dbp, ret, "DB->get");
        goto err;
    }

    err:    if ((t_ret = dbp->close(dbp, 0)) != 0 && ret == 0)
        ret = t_ret; 

        exit(ret);
    }

int main(void)
{
  CURL *curl;
  CURLcode res;

  struct MemoryStruct chunk;

  chunk.memory = malloc(1);  /* will be grown as needed by the realloc above */ 
  chunk.size = 0;    /* no data at this point */

  struct curl_slist *headerlist=NULL;

  const char *temp = "<?xml version=\"1.0\" encoding=\"utf-8\"?> <S:Envelope xmlns:S=\"http://schemas.xmlsoap.org/soap/envelope/\">  <S:Header/>  <S:Body> <ns2:getExtracurricular xmlns:ns2=\"http://desktop/\"> <deviceID>10:2E:AF:EB:6F:DB</deviceID> </ns2:getExtracurricular> </S:Body> </S:Envelope>";

  curl = curl_easy_init();
  if(curl) {
    /* First set the URL that is about to receive our POST. This URL can
       just as well be a https:// URL if that is what should receive the
       data. */ 
    curl_easy_setopt(curl, CURLOPT_URL, "http://eon.sdsu.edu:8080/SmartbadgePortal/PersonalInterestsService");
    /* Now specify the POST data */ 
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    headerlist = curl_slist_append(headerlist, "Content-Type: text/xml");

    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, temp);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
    /* send all data to this function  */ 
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);

  /* we pass our 'chunk' struct to the callback function */ 
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);

    /* Perform the request, res will get the return code */ 
    res = curl_easy_perform(curl);

    printf("%lu bytes retrieved\n", (long)chunk.size);
    //printf("%s data received\n", chunk.memory);

    token = strstr(chunk.memory, begin);
    json = token + strlen(begin);
    token = strstr(json, end);
    *token = 0x00;
    printf("%s\n",json);

    newstr = replace(json, "&quot;", "\"");
    printf("%s\n",newstr);
    str = replace(newstr, "\"", "\\\"");
    printf("%s\n",str);
    str1 = replace(str, "\"[", "\"");
    printf("%s\n",str1);
    str2 = replace(str1, "]\\" , "\\");
    printf("%s\n",str2);
    str3 = replace(str2, "{"  , "\"{");
    printf("%s\n",str3);
    finalstr = replace(str3, "}" , "}\"");
    str4 = replace(finalstr, "))1" , "");

printf("%s\n", finalstr);

    printf ("JSON string: %s\n", str4);
    json_parse(str4);

  if(chunk.memory)
    free(chunk.memory);

    /* always cleanup */ 
    curl_easy_cleanup(curl);
  }

  return 0;

  }

I am getting segmentation error when I am passing a string to my JSON function. I did gdb and below is my error result:

(gdb) print str
$1 = 0x28c90 "\"{\\\"1\\\":\\\"25,11,10,2,87,84,85,67\\\"}\"\251\002"
(gdb) print str4
$2 = 0x28c90 "\"{\\\"1\\\":\\\"25,11,10,2,87,84,85,67\\\"}\"\251\002"
(gdb) print finalstr
$3 = 0x28c60 "\"{\\\"1\\\":\\\"25,11,10,2,87,84,85,67\\\"}\"))1"
(gdb) print str3
$4 = 0x28c30 "\"{\\\"1\\\":\\\"25,11,10,2,87,84,85,67\\\"}))1"
(gdb) print str2
$5 = 0x28c08 "{\\\"1\\\":\\\"25,11,10,2,87,84,85,67\\\"}))1"
(gdb) print str1
$6 = 0x28be0 "{\\\"1\\\":\\\"25,11,10,2,87,84,85,67]\\\"}))"
(gdb) print str
$7 = 0x28c90 "\"{\\\"1\\\":\\\"25,11,10,2,87,84,85,67\\\"}\"\251\002"
(gdb) print newstr
$8 = 0x28a50 "{\"1\":\"[25,11,10,2,87,84,85,67]\"}"

So I feel there is some problem in the way my replace function is working, because it is adding extra characters to my string "\251\002", while sending.

if anybody can help me with it, it would be great. Thanks!!!


回答1:


while (*s) {
  if (strstr(s, old) == s) {
     strcpy(&ret[i], new);
  i += newlen;
  s += oldlen;
} else
ret[i++] = *s++;
}

You are forgetting to copy the part of the string before strstr found a match.

UPDATE: You seem to have a strange way of stepping throug the string. Why not use the returned pointer and copy from i upto that (pointer-s) ?




回答2:


ret = malloc(i + count * (newlen - oldlen)); is short by 1.
Use ret = malloc(i + count * (newlen - oldlen) + 1);

Ref



来源:https://stackoverflow.com/questions/7842855/some-error-while-performing-string-operations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!