#include <stdio.h> #include <stdlib.h> #include <string.h> #include <jansson.h> #include <ctype.h> #include <openssl/hmac.h> typedef struct { char key[256]; char value[256]; } KeyValue; int compare(const void a, const void b) { return strcmp(((KeyValue)a)->key, ((KeyValue)b)->key); } // 将KeyValue数组按ASCII码升序排序并拼接成URL键值对形式的字符串 char *sort_dict(KeyValue *array, int size) { // 对KeyValue数组按ASCII码升序排序 qsort(array, size, sizeof(KeyValue), compare); // 初始化一个字符串,用于存储拼接后的URL键值对形式的字符串 char *query_list = malloc(size * 256); int len=0; for(int i=0; i<size; i++) { // 如果值为空或者空字符串则不拼接 if(strlen(array[i].value)==0){ continue; } char *key = array[i].key; char *value = array[i].value; // 如果值是字母或数字,则直接拼接 if(isalpha(value[0]) && isalnum(value[1]) && strcmp(value, "true")!=0 && strcmp(value, "false")!=0) { sprintf(&query_list[len], "%s=%s&", key, value); } else { // 否则需要将值加上双引号再拼接 sprintf(&query_list[len], "%s="%s"&", key, value); } len = strlen(query_list); } // 去掉最后一个&符号 if(len>0) { query_list[len-1] = 0; } return query_list; } void traverse(json_t *root, const char *prefix,int i,KeyValue *array) { if (json_is_object(root)) { const char *key; json_t *value; json_object_foreach(root, key, value) { char new_prefix[3000]; if (strlen(prefix) == 0) { sprintf(new_prefix, "%s", key); } else { if (json_is_array(value)) { sprintf(new_prefix, "%s[%d].%s", prefix, json_array_size(value) - 1, key); } else { sprintf(new_prefix, "%s.%s", prefix, key); } } traverse(value, new_prefix,i,array); } } else if (json_is_array(root)) { size_t i; json_t *value; json_array_foreach(root, i, value) { char new_prefix[3000]; sprintf(new_prefix, "%s[%d]", prefix, i); traverse(value, new_prefix,i,array); } } else { if (json_is_integer(root)) { int value = json_integer_value(root); char valuestr[20]; sprintf(valuestr, "%d", value); array[i].key=prefix;array[i].value=valuestr; i=i+1; printf("%s=%d\n", prefix, value); } else { const char *value = json_string_value(root); array[i].key=prefix;array[i].value=valuestr; i=i+1; printf("%s=%s\n", prefix, value); } } } int main() { char *json_str = "{"name":"John","age":30,"cars":[{"model":"X1","year":2020},{"model":"X3","year":2021}]}"; json_error_t error; json_t *root = json_loads(json_str, 0, &error); int len = strlen(json_str); KeyValue *array = malloc(len * sizeof(KeyValue)); int i=0; traverse(root, "",i,array); json_decref(root); return 0; }上面代码存在什么问题
时间: 2024-04-04 17:28:58 浏览: 25
这段代码存在几个问题:
1. `compare` 函数的参数类型应该是 `const void *` 而非 `const void`。
2. 在 `sort_dict` 函数中,如果 `value` 为空或空字符串,则不应该跳过,应该将其值设为 `null` 或 `""`。
3. 在 `sort_dict` 函数中,对于需要加上双引号的值,应该用反斜杠对字符串内的双引号进行转义,以免出现语法错误。
4. 在 `traverse` 函数中,对 `array` 数组赋值时,应该使用 `strcpy` 函数,而非直接将指针赋值给结构体成员变量。
5. 在 `traverse` 函数中,如果 `json_string_value` 返回的是 `NULL`,则无法将值存入结构体中,需要对这种情况进行特殊处理。
相关问题
将下面代码中结构体的定义变为指针 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <jansson.h> typedef struct { char vin[20]; long timestamp; char sdkVersion[128]; char deviceId[20]; } MyStruct; int main() { MyStruct s = { .vin = "12345", .timestamp = 1614279599, .sdkVersion = "1.0.0", .deviceId = "67890" }; // Convert struct to JSON json_t *root = json_object(); json_object_set_new(root, "vin", json_string(s.vin)); json_object_set_new(root, "timestamp", json_integer(s.timestamp)); json_object_set_new(root, "sdkVersion", json_string(s.sdkVersion)); json_object_set_new(root, "deviceId", json_string(s.deviceId)); char *json_str = json_dumps(root, JSON_INDENT(2)); printf("%s\n", json_str); // Clean up free(json_str); json_decref(root); return 0; }
下面是将结构体定义为指针并修改相关代码的示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <jansson.h>
typedef struct {
char vin[20];
long timestamp;
char sdkVersion[128];
char deviceId[20];
} *MyStructPtr;
int main() {
MyStructPtr s = malloc(sizeof(*s));
strcpy(s->vin, "12345");
s->timestamp = 1614279599;
strcpy(s->sdkVersion, "1.0.0");
strcpy(s->deviceId, "67890");
// Convert struct to JSON
json_t *root = json_object();
json_object_set_new(root, "vin", json_string(s->vin));
json_object_set_new(root, "timestamp", json_integer(s->timestamp));
json_object_set_new(root, "sdkVersion", json_string(s->sdkVersion));
json_object_set_new(root, "deviceId", json_string(s->deviceId));
char *json_str = json_dumps(root, JSON_INDENT(2));
printf("%s\n", json_str);
// Clean up
free(json_str);
json_decref(root);
free(s);
return 0;
}
```
在新代码中, `MyStruct` 被定义为指针类型 `MyStructPtr`,在 `main()` 函数中使用 `malloc()` 分配内存来创建 `MyStruct` 的实例,并使用 `->` 运算符来访问结构体成员。其余部分与之前的代码类似。
输出结果与之前的示例代码相同。
c语言 检查一下下面的代码 为什么函数中获取不到键值#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <openssl/ssl.h> #include <openssl/err.h> #include <openssl/hmac.h> #include <jansson.h> #include <time.h> #include <errno.h> #include <resolv.h> #include <netdb.h> char* calculate_signature(char* json_str, char* key) { json_t *root; json_error_t error; /* 从文件中读取 JSON 数据 */ root = json_load_file(json_str, 0, &error); /* 遍历 JSON 对象中的所有键值对,并获取键的名称 */ int key_count = json_object_size(root); printf("key_names %d\n", key_count); const char *key_name; json_t *value; const char **key_names = (const char **)malloc(key_count * sizeof(char *)); int i = 0; json_object_foreach(root, key_name, value) { key_name = json_object_iter_key(value); key_names[i] = key_name; i++; } printf("key_names %s\n", key_names[2]); //int str_num = i; // 计算字符串数组中的字符串数量 /* char **sorted_names = sort_strings(key_names, key_count); char* stringA = (char*)malloc(1); // 初始化为一个空字符串 stringA[0] = '\0'; size_t len = 0; for (int i = 0; i < str_num; i++) { char* key = sorted_names[i]; json_t* value = json_object_get(root, key); char* str = json_dumps(value, JSON_ENCODE_ANY | JSON_COMPACT); len += strlen(key) + strlen(str) + 2; // 2 是键值对之间的字符 stringA = (char*)realloc(stringA, len); strcat(stringA, key); strcat(stringA, "="); strcat(stringA, str); strcat(stringA, "&"); free(str); } free(sorted_names); stringA[strlen(stringA) - 1] = '\0'; // 去掉最后一个"&" printf("stringA%s\n", stringA); unsigned char* sign = (unsigned char*)malloc(EVP_MAX_MD_SIZE); unsigned int sign_len = 0; HMAC(EVP_sha256(), key, strlen(key), (unsigned char*)stringA, strlen(stringA), sign, &sign_len); // 计算HMAC-SHA256签名 char* signature = (char*)malloc(sign_len * 2 + 1); // 签名的十六进制表示 signature[0] = '\0'; // 初始化为一个空字符串 for (int i = 0; i < sign_len; i++) { sprintf(signature + i * 2, "%02x", sign[i]); } json_object_set_new(root, "sign", json_string(signature)); // 在json中添加"sign"参数 json_dumpf(root, stdout, JSON_ENCODE_ANY | JSON_COMPACT); // 输出带有"sign"参数的json字符串 json_decref(root); free(key_names); free(stringA); free(sign); printf("signature%s\n", signature); */ return("A"); } int main() { char *key="39cabdfaab8c4da09bd6e9823c527836"; char *sss="{\"timestamp\":1685509898,\"sdkVersion\":\"1.0.30_1\",\"vin\":\"LJUBMSA24PKFFF198\"}"; calculate_signature(sss, key) ; }
代码中的问题在于 `json_load_file` 函数的第一个参数应该是一个文件名字符串,而不是 JSON 字符串。因此,需要将 `calculate_signature` 函数中的第一个参数 `json_str` 修改为文件名。
修改后的代码如下:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
#include <jansson.h>
#include <time.h>
#include <errno.h>
#include <resolv.h>
#include <netdb.h>
char* calculate_signature(char* filename, char* key) {
json_t *root;
json_error_t error;
/* 从文件中读取 JSON 数据 */
root = json_load_file(filename, 0, &error);
if (!root) {
printf("Error in %s line %d: %s\n", error.source, error.line, error.text);
return NULL;
}
/* 遍历 JSON 对象中的所有键值对,并获取键的名称 */
int key_count = json_object_size(root);
printf("key_names %d\n", key_count);
const char *key_name;
json_t *value;
const char **key_names = (const char **)malloc(key_count * sizeof(char *));
int i = 0;
json_object_foreach(root, key_name, value) {
key_name = json_object_iter_key(value);
key_names[i] = key_name;
i++;
}
printf("key_names %s\n", key_names[2]);
//int str_num = i; // 计算字符串数组中的字符串数量
/*
char **sorted_names = sort_strings(key_names, key_count);
char* stringA = (char*)malloc(1); // 初始化为一个空字符串
stringA[0] = '\0';
size_t len = 0;
for (int i = 0; i < str_num; i++) {
char* key = sorted_names[i];
json_t* value = json_object_get(root, key);
char* str = json_dumps(value, JSON_ENCODE_ANY | JSON_COMPACT);
len += strlen(key) + strlen(str) + 2; // 2 是键值对之间的字符
stringA = (char*)realloc(stringA, len);
strcat(stringA, key);
strcat(stringA, "=");
strcat(stringA, str);
strcat(stringA, "&");
free(str);
}
free(sorted_names);
stringA[strlen(stringA) - 1] = '\0'; // 去掉最后一个"&"
printf("stringA%s\n", stringA);
unsigned char* sign = (unsigned char*)malloc(EVP_MAX_MD_SIZE);
unsigned int sign_len = 0;
HMAC(EVP_sha256(), key, strlen(key), (unsigned char*)stringA, strlen(stringA), sign, &sign_len); // 计算HMAC-SHA256签名
char* signature = (char*)malloc(sign_len * 2 + 1); // 签名的十六进制表示
signature[0] = '\0'; // 初始化为一个空字符串
for (int i = 0; i < sign_len; i++) {
sprintf(signature + i * 2, "%02x", sign[i]);
}
json_object_set_new(root, "sign", json_string(signature)); // 在json中添加"sign"参数
json_dumpf(root, stdout, JSON_ENCODE_ANY | JSON_COMPACT); // 输出带有"sign"参数的json字符串
json_decref(root);
free(key_names);
free(stringA);
free(sign);
printf("signature%s\n", signature);
*/
return("A");
}
int main() {
char *key="39cabdfaab8c4da09bd6e9823c527836";
char *filename="test.json";
calculate_signature(filename, key) ;
return 0;
}
```
另外,代码中还有一些注释掉的部分,需要先实现对应的函数才能使用。
相关推荐
![exe](https://img-home.csdnimg.cn/images/20210720083343.png)
![text/x-c](https://img-home.csdnimg.cn/images/20210720083646.png)
![application/msword](https://img-home.csdnimg.cn/images/20210720083327.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)