在處理 JSON 數據時,通常默認是無序的。但是在某些場景下,我們可能希望保持 JSON 數據的固定順序,比如在進行數據簽名和驗簽時就必需保證數據的順序不變。
C 語言中,我們可以使用 cJSON 庫來處理 JSON 數據。cJSON 是一個非常輕量級的 JSON 庫,能夠高效地處理 JSON 數據。
在 cJSON 庫中,可以使用 cJSON_Print 函數來將 JSON 數據以字符串的形式輸出。但是在默認情況下,輸出的 JSON 數據是無序的。
cJSON* root = cJSON_CreateObject(); cJSON_AddStringToObject(root, "name", "Tom"); cJSON_AddNumberToObject(root, "age", 18); cJSON_AddStringToObject(root, "address", "Beijing"); char* json_str = cJSON_Print(root); printf("%s\n", json_str); // 輸出結果如下: // {"name":"Tom", "address":"Beijing", "age":18}
為了保持 JSON 數據的固定順序,我們需要手動進行排序。cJSON 庫提供了一個 cJSON_ArrayForEach 宏,可以方便地遍歷 JSON 對象的所有 key。
// 將 JSON 對象的 key 按字典序排序 void cJSON_SortObject(cJSON* root) { int i, j, size = cJSON_GetArraySize(root); cJSON* child; char** keys = (char**)malloc(size * sizeof(char*)); for (i = 0, child = root->child; i< size && child; i++, child = child->next) { keys[i] = child->string; } qsort(keys, size, sizeof(char*), compare_keys); for (i = 0; i< size; i++) { for (j = i, child = root->child; j< size && child; j++, child = child->next) { if (strcmp(keys[i], child->string) == 0) { cJSON_DeleteItemFromObject(root, keys[i]); cJSON_AddItemToObject(root, keys[i], child); break; } } } free(keys); }
在排序完成后,再輸出 JSON 數據即可保持固定順序。
cJSON_SortObject(root); char* json_str = cJSON_Print(root); printf("%s\n", json_str); // 輸出結果如下: // {"address":"Beijing", "age":18, "name":"Tom"}