Некоторая ошибка при выполнении строковых операций

Ниже мой код:

#include  #include  #include  #include  #include  #include  #include  #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 = ""; char *end = ""; 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 = "     10:2E:AF:EB:6F:DB   "; 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, """, "\""); 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; } 

Я получаю ошибку сегментации, когда передаю строку своей функции JSON. Я сделал gdb, а ниже – результат моей ошибки:

 (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]\"}" 

Поэтому я чувствую, что есть некоторая проблема в том, как работает моя функция замены, потому что она добавляет дополнительные символы в мою строку «\ 251 \ 002» при отправке.

если кто-нибудь может мне помочь, это было бы здорово. Спасибо!!!

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

Вы забываете скопировать часть строки, прежде чем strstr найдет совпадение.

UPDATE: У вас, кажется, странный способ пошагово. Почему бы не использовать возвращаемый указатель и скопировать с i до этого (указатели)?

ret = malloc(i + count * (newlen - oldlen)); короче 1.
Использовать ret = malloc(i + count * (newlen - oldlen) + 1);

ссылка