以下是我的代码:
#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, """, "\"");
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”中添加额外的字符。
如果有人可以帮助我,那就太好了。感谢!!!
答案 0 :(得分:0)
while (*s) {
if (strstr(s, old) == s) {
strcpy(&ret[i], new);
i += newlen;
s += oldlen;
} else
ret[i++] = *s++;
}
在 strstr找到匹配项之前,您忘记复制字符串的一部分。
更新:你似乎有一种奇怪的方式踩到弦。为什么不使用返回的指针并从i复制到(指针-s)?
答案 1 :(得分:0)
ret = malloc(i + count * (newlen - oldlen));
缩短为1.
使用ret = malloc(i + count * (newlen - oldlen) + 1);