执行字符串操作时出现一些错误
下面是我的代码:
#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”添加了额外的字符。
如果有人能帮助我,那就太好了。谢谢!!!
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, """, "\"");
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!!!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您忘记在 strstr 找到匹配项之前复制字符串的部分。
更新:你似乎有一种奇怪的方式来遍历字符串。为什么不使用返回的指针并从 i 复制到 (pointer-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) ?
ret = malloc(i + count * (newlen - oldlen));
短了 1。使用 ret = malloc(i + count * (newlen - oldlen) + 1);
参考
ret = malloc(i + count * (newlen - oldlen));
is short by 1.Use
ret = malloc(i + count * (newlen - oldlen) + 1);
Ref