Loading

解决Windows下json.hpp中文乱码问题

文中使用的是 json 库,整个库的代码由一个单独的头文件json.hpp组成,用普通的C++11编写的。它没有库,没有子项目,没有依赖关系,没有复杂的构建系统,使用起来很方便。

先引用头文件和命名空间:

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <Windows.h>
#include "json.hpp"

using namespace std;
using namespace nlohmann;

json.hpp默认使用UTF8编码,在有中文情况下直接读取string会乱码,需要提供UTF8和string互相转换的函数

std::string UTF8_To_string(const std::string& str)
{
    int nwLen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);    
    wchar_t* pwBuf = new wchar_t[nwLen + 1];//加1用于截断字符串 
    memset(pwBuf, 0, nwLen * 2 + 2);

    MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), pwBuf, nwLen);

    int nLen = WideCharToMultiByte(CP_ACP, 0, pwBuf, -1, NULL, NULL, NULL, NULL);

    char* pBuf = new char[nLen + 1];
    memset(pBuf, 0, nLen + 1);

    WideCharToMultiByte(CP_ACP, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);

    std::string retStr = pBuf;

    delete[]pBuf;
    delete[]pwBuf;

    pBuf = NULL;
    pwBuf = NULL;

    return retStr;
}

std::string string_To_UTF8(const std::string& str)
{
    int nwLen = ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);

    wchar_t* pwBuf = new wchar_t[nwLen + 1];//加1用于截断字符串 
    ZeroMemory(pwBuf, nwLen * 2 + 2);

    ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), pwBuf, nwLen);

    int nLen = ::WideCharToMultiByte(CP_UTF8, 0, pwBuf, -1, NULL, NULL, NULL, NULL);

    char* pBuf = new char[nLen + 1];
    ZeroMemory(pBuf, nLen + 1);

    ::WideCharToMultiByte(CP_UTF8, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);

    std::string retStr(pBuf);

    delete[]pwBuf;
    delete[]pBuf;

    pwBuf = NULL;
    pBuf = NULL;

    return retStr;
}

先定义一个file.json文件如下:

{
  "pi": 3.141,
  "happy": true,
  "name": "Niels中文",
  "nothing": null,
  "answer": {
    "everything": 42
  },
  "list": [1, 0, 2],
  "object": {
    "currency": "USD",
    "value": 42.99
  }
}

修改其中的name字段并保存,代码如下:

int main()
{
    // read a JSON file
    std::ifstream iStream("file.json");
    json jsonObj;
    iStream >> jsonObj;

    string strName = jsonObj["name"];
    string str = UTF8_To_string(strName);
    str = str + "测试";
    jsonObj["name"] = string_To_UTF8(str);

    // write prettified JSON to another file
    std::ofstream oStream("pretty.json");
    oStream << std::setw(4) << jsonObj << std::endl;

    return 0;
}

最后生成的pretty.json如下:

{
    "answer": {
        "everything": 42
    },
    "happy": true,
    "list": [
        1,
        0,
        2
    ],
    "name": "Niels中文测试",
    "nothing": null,
    "object": {
        "currency": "USD",
        "value": 42.99
    },
    "pi": 3.141
}
posted @ 2023-03-14 23:26  二次元攻城狮  阅读(607)  评论(1编辑  收藏  举报