执行字符串操作时出错

时间:2011-10-20 22:05:45

标签: c string json libcurl berkeley-db

以下是我的代码:

#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;

  }

当我将字符串传递给我的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”中添加额外的字符。

如果有人可以帮助我,那就太好了。感谢!!!

2 个答案:

答案 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);

Ref