在使用C語言中的json庫時(shí),有時(shí)會(huì)遇到一個(gè)問題,就是讀取json文件中的中文字符會(huì)出現(xiàn)亂碼。這是因?yàn)樵谧x取時(shí)沒有正確地設(shè)置字符編碼格式。接下來我們就來看看如何解決這個(gè)問題。
首先,我們需要知道json文件一般使用的是UTF-8編碼格式。因此,在讀取文件時(shí)需要使用相應(yīng)的編碼格式進(jìn)行解碼。
// 使用UTF-8編碼格式打開并讀取json文件 FILE* fp = fopen("test.json", "rb"); fseek(fp, 0, SEEK_END); long len = ftell(fp); fseek(fp, 0, SEEK_SET); char* buffer = (char*)malloc(len + 1); fread(buffer, 1, len, fp); buffer[len] = '\0'; json_object* jobj = json_tokener_parse(buffer);
在上面的代碼中,我們使用了rb模式打開文件,保證了文件以二進(jìn)制方式讀取,并且使用了malloc動(dòng)態(tài)分配內(nèi)存。fseek函數(shù)的作用是將文件指針移動(dòng)到文件尾部,再使用ftell函數(shù)獲取文件長(zhǎng)度,最后將文件指針移動(dòng)到文件開頭。接著使用json_tokener_parse函數(shù)解析json文件。
但此時(shí)讀取到的中文字符還是會(huì)出現(xiàn)亂碼。這是因?yàn)樵诮馕鲎址畷r(shí)需要使用相應(yīng)的字符編碼格式解碼,接下來我們看看如何完成該操作。
// 使用UTF-8編碼格式解析json字符串 json_tokener* tok = json_tokener_new(); struct json_object* jobj = NULL; while(buffer[i] != '\0') { jobj = json_tokener_parse_ex(tok, &buffer[i], strlen(&buffer[i])); if(tok->err != json_tokener_success) { printf("Error: %s\n", json_tokener_error_desc(tok->err)); break; } i += tok->char_offset; } json_tokener_free(tok);
在上面的代碼中,我們使用了json_tokener_parse_ex函數(shù)解析json字符串,并且使用了json_tokener_new函數(shù)創(chuàng)建json_tokener對(duì)象。其中,i表示當(dāng)前讀取到的位置,tok->char_offset表示解析出的字符串長(zhǎng)度。使用json_tokener_error_desc函數(shù)可以獲取解析錯(cuò)誤的描述信息。
最后,我們需要注意的是在輸出json字符串時(shí)需要使用相應(yīng)的字符編碼格式編碼,否則輸出的中文字符還是會(huì)出現(xiàn)亂碼的問題。
// 使用UTF-8編碼格式輸出json字符串 json_object* json_obj = json_object_new_object(); json_object_object_add(json_obj, "name", json_object_new_string("小明")); json_object_object_add(json_obj, "age", json_object_new_int(18)); const char* json_str = json_object_to_json_string_ext(json_obj, JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY); printf("json_str: %s\n", json_str); json_object_put(json_obj);
在上面的代碼中,我們使用了json_object_to_json_string_ext函數(shù)輸出json字符串,其中使用了JSON_C_TO_STRING_SPACED和JSON_C_TO_STRING_PRETTY兩個(gè)選項(xiàng),保證輸出的json字符串格式良好,并且使用了const char*類型保存json字符串,保證了輸出時(shí)不會(huì)出現(xiàn)亂碼。