如何从头文件读取结构体标签并匹配JSON配置的结构体类型?
Alright, let's break down how to solve this problem—mapping JSON configuration entries to your C structs defined in header.h and populating them correctly. Here's a practical, step-by-step approach:
1. Pick a JSON Parser Library
First, you'll need a way to parse the JSON file in C. cJSON is a great lightweight option (no external dependencies, easy to drop into your project). It’s perfect for straightforward use cases like this.
2. Your Struct Definitions (From
header.h) Let’s restate your header for clarity, adding the necessary includes to make it compile:
// header.h #include <stdint.h> #include <stdbool.h> typedef struct { uint32_t hola; uint32_t adios; } Signal_t; typedef struct { bool goodbye; uint32_t hello; } FrameTx_t;
3. Parse JSON & Map to Structs
The core logic is:
- Read the JSON file into a string
- Parse the JSON root object
- Identify the top-level key (this is your struct type name, e.g., "Signal_t")
- Extract values from the JSON and assign them to the matching struct’s members
Here’s a complete, working example:
#include <stdio.h> #include <stdlib.h> #include "cJSON.h" #include "header.h" // Helper to read JSON file into a string char* read_json_file(const char* filename) { FILE* file = fopen(filename, "r"); if (!file) { perror("Failed to open JSON file"); return NULL; } // Get file size fseek(file, 0, SEEK_END); long file_size = ftell(file); fseek(file, 0, SEEK_SET); char* json_str = malloc(file_size + 1); if (!json_str) { perror("Failed to allocate memory for JSON"); fclose(file); return NULL; } fread(json_str, 1, file_size, file); json_str[file_size] = '\0'; fclose(file); return json_str; } int main() { char* json_str = read_json_file("JSON_File.txt"); if (!json_str) return 1; cJSON* root = cJSON_Parse(json_str); if (!root) { fprintf(stderr, "JSON parse error: %s\n", cJSON_GetErrorPtr()); free(json_str); return 1; } // Check for Signal_t config cJSON* signal_obj = cJSON_GetObjectItemCaseSensitive(root, "Signal_t"); if (cJSON_IsObject(signal_obj)) { Signal_t signal_cfg = {0}; // Initialize to safe defaults // Populate hola cJSON* hola_val = cJSON_GetObjectItemCaseSensitive(signal_obj, "hola"); if (cJSON_IsNumber(hola_val)) { signal_cfg.hola = (uint32_t)hola_val->valueint; } // Populate adios cJSON* adios_val = cJSON_GetObjectItemCaseSensitive(signal_obj, "adios"); if (cJSON_IsNumber(adios_val)) { signal_cfg.adios = (uint32_t)adios_val->valueint; } // Use the configured struct (example output) printf("Configured Signal_t:\n hola = %u\n adios = %u\n", signal_cfg.hola, signal_cfg.adios); } // Check for FrameTx_t config else if ((signal_obj = cJSON_GetObjectItemCaseSensitive(root, "FrameTx_t")) != NULL && cJSON_IsObject(signal_obj)) { FrameTx_t frame_tx_cfg = {0}; // Populate goodbye cJSON* goodbye_val = cJSON_GetObjectItemCaseSensitive(signal_obj, "goodbye"); if (cJSON_IsBool(goodbye_val)) { frame_tx_cfg.goodbye = (bool)cJSON_IsTrue(goodbye_val); } // Populate hello cJSON* hello_val = cJSON_GetObjectItemCaseSensitive(signal_obj, "hello"); if (cJSON_IsNumber(hello_val)) { frame_tx_cfg.hello = (uint32_t)hello_val->valueint; } // Use the configured struct (example output) printf("Configured FrameTx_t:\n goodbye = %s\n hello = %u\n", frame_tx_cfg.goodbye ? "true" : "false", frame_tx_cfg.hello); } else { fprintf(stderr, "Unrecognized struct type in JSON\n"); } // Cleanup resources cJSON_Delete(root); free(json_str); return 0; }
4. Key Tips for Robustness
- Type Validation: Always check JSON value types (e.g., confirm "hola" is a number) before casting—this prevents undefined behavior from bad JSON.
- Case Sensitivity: The example uses
cJSON_GetObjectItemCaseSensitive—ensure your JSON keys match struct/member names exactly (case included). - Default Values: Initialize structs to zero (like
Signal_t signal_cfg = {0};) so unconfigured members have safe, predictable values. - Required Members: If certain fields are mandatory, add checks to throw errors if they’re missing from the JSON.
5. Compilation
If you’re using cJSON, compile with:
gcc your_source_file.c cJSON.c -o config_parser -lm
The -lm links the math library, which cJSON uses for number handling.
内容的提问来源于stack exchange,提问作者Cuboscar95
相关产品推荐
相关产品推荐

