战网中国

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz

MFC使用的json11

已有 772 次阅读2023-8-15 16:25 |个人分类:program

C++类编程语言要解析json就没有C#那样便利了,由于Newtonsoft.Json程序包已经将在C#中使用json变得如同使用string那样简单!然而C++中就没有那样便利了!于是各种c/c++语言高手就各显神通,做出各种json解析代码,网络上搜索到人气高的目前主要有:rapidjson、json11(dropbox的,并有在此基础上修正的各种)、cJSON、jsoncpp等等。
但我在MFC中使用上述的json时,或多或少都会遇到麻烦,特别是中文字符的解析基本都是??,于是我就想搞一下在MFC使用的轻便的json。想到就做,于是便从dropbox的json11入手,将其移植到MFC中。
为了测试,先建立一个简单的对话框程序,上面只有一个edit control和一个button,如下图:


测试的json文件如下(data.json):

{"name": "spring","address": "北京","age": 30,"value1": [[23, 43], [-80, 6, 90]],

"value2": [13.3, 1.9, 2.10],

"bei_jing": {"address": "海淀","car": "ferrari","cat": true},

"shan_dong": {"address": "济南","value1": [{"ji_nan": "趵突泉"}, {"tai_an": "泰山"}]}}

主要做的工作就是dropbox的json11使用的是stl的string,将其改成MFC的CString,这样在MFC中就无需再进行CString与string之间的转换,同时采用TCHAR类的智能字符,这样也就不用理会是Unicode还是多字符集的问题啦。

测试的MFC部分的代码如下:

void CMFCJsonDlg::OnBnClickedButtonRead()

{  

    // TODO: Add your control notification handler code here

    FILE *fStream = NULL;

    errno_t e = _tfopen_s(&fStream, TEXT(".\\data.json"), TEXT("rt,ccs=UTF-8"));


    if (e != 0)

        return;


    //read json file

    CStdioFile rFile(fStream);

    CStringList strlist;

    try

    {

        CString strtmp;

        while (rFile.ReadString(strtmp) != NULL) {

            strlist.AddTail(strtmp);

        }

    }

    catch (CException* e)

    {

       e->ReportError();

    }

    rFile.Close();


    //put reading data into CString

    CString str;

    POSITION pos = strlist.GetHeadPosition();

    while (pos != NULL) {

        str += strlist.GetNext(pos);

    }

    //Json data show

    CString err;

    const auto json = CJson::parse(str, err);

    CString jstr;

    int i = json[TEXT("age")].int_value();

    CString sz;

    sz.Format(TEXT("age: %d"), i);

    jstr = TEXT("name: ") + json[TEXT("name")].string_value()+TEXT("\r\n");

    jstr += TEXT("address: ") + json[TEXT("address")].string_value() + TEXT("\r\n");

    jstr += TEXT("age: ") + sz + TEXT("\r\n");

    auto& k = json[TEXT("bei_jing")].object_items();

    for (auto it : k) {

        if ((it.second).is_string())

            jstr += it.first + TEXT(": ") + (it.second).string_value() + TEXT("\r\n");

        if ((it.second).is_bool()) {

            if((it.second).bool_value())

            jstr += it.first + TEXT(": true") + TEXT("\r\n");

            if (!(it.second).bool_value())

                jstr += it.first + TEXT(": false") + TEXT("\r\n");

        }

    }


    auto& obj = json[TEXT("shan_dong")].object_items();

    for (auto sub : obj) {

        if (sub.first == TEXT("address")) {

            jstr += TEXT("address: ") + sub.second.string_value() + TEXT("\r\n");

        }

        if (sub.first == TEXT("value1")) {

            if ((sub.second).is_array()) {

                for(auto& o : (sub.second).array_items()){

                    for (auto z : o.object_items()) {

                        jstr += z.first + TEXT(": ") + (z.second).string_value() + TEXT("\r\n");

                    }

                }

            }

            else {

                jstr += TEXT("next is wrong");

            }

        }

    }


     auto& ar = json[TEXT("value1")].array_items();

     CString st;

     for (auto it = ar.begin(); it != ar.end(); it++) {

         for (auto v : it->array_items()) {

             st.Format(TEXT("%d"), v.int_value());

             jstr += st + TEXT("\r\n");

        }

    }


    auto& arr = json[TEXT("value2")].array_items();

    for (auto elem : arr) {

        CString st;

        if (elem.is_number()) {

            st.Format(TEXT("%.10g"), elem.number_value());

            jstr += st + TEXT("\r\n");

        }

        if (elem.is_array()) {

            for (auto suba : elem.array_items()) {

                if (suba.is_number()) {

                    st.Format(TEXT("%.10g"), elem.number_value());

                    jstr += st + TEXT("\r\n");

                }

            }

        }

    }

    //test CJson literals

    CJson ob = CJson::cobject{ 

        { TEXT("k1"),TEXT("v1") }, 

        { TEXT("k2"), 33 }, 

        { TEXT("k3"), CJson::carray({TEXT("a"),-3.2,true,false,nullptr}) },

    };

    CString test = ob.dump();

     jstr += test;

     SetDlgItemTextW(IDC_EDIT_SHOW, jstr);

}

测试代码的前大半部分是从data.json文件读取json字符串再根据字符串内容进行解析,最后再测试程序中构造json字符串,再检测dump的效果,测试结果如下图。



从上图可以看到,转换后的json11在MFC中解析中文完全没有问题,至少自己使用足够了。


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 立即注册

Archiver|手机版|小黑屋|BattleCN ( 陕ICP备05006600号 )

GMT+8, 2024-4-28 20:36 , Processed in 0.085248 second(s), 16 queries .

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

返回顶部