VC++ 解析JSON 学习总结

707 篇文章 ¥99.90 ¥299.90
本文详细介绍了在VC++环境下如何使用JsonCPP库来解析和处理JSON字符串,包括从网页获取JSON数据并进行解析的具体步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

介绍 JSON

http://www.json.org/json-zh.html


JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 JSON采用完全独立于语言的文本格式


,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 这些特性使JSON成为理想的数据交换语言。


JSON建构于两种结构:


“名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。
值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。
这些都是常见的数据结构。事实上大部分现代计算机语言都以某种形式支持它们。这使得一种数据格式在同样基于这些结构的编程语言之间交换成为可能。


JSON具有以下这些形式:


对象是一个无序的“‘名称/值’对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。


数组是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间使用“,”(逗号)分隔。


值(value)可以是双引号括起来的字符串(string)、数值(number)、true、false、 null、对象(object)或者数组(array)。这些结构可以嵌套。


字符串(string)是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。


字符串(string)与C或者Java的字符串非常相似。


数值(number)也与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。


空白可以加入到任何符号之间。 以下描述了完整的语言。
========

VC++ 解析JSON字串

http://blog.youkuaiyun.com/wangji163163/article/details/8754411
一、摘要 
       JSON 的全称为:JavaScript Object Notation,顾名思义,JSON 是用于标记 Javascript 对象的,JSON 官方的解释为:JSON 是一种轻量级的数据传输格式。
       本文并不详细介绍 JSON 本身的细节,旨在讨论如何使用 C++ 语言来处理 JSON。关于 JSON 更具体的信息,可参见 JSON 官网:http://www.json.org。


二、本文选择处理 JSON的 C++ 库
       本文选择一个第三方库 jsoncpp 来解析 JSON。jsoncpp 是比较出名的 C++ JSON 解析库。在 JSON 官网也是首推的。
       下载地址为:
                           http://sourceforge.net/projects/jsoncpp (本文使用的 jsoncpp 版本为:0.5.0)


三、jsoncpp 在 Windows 下的编译
       要使用第三方源码库,第一步少不了的就是编译,将源码文件编译成我们方便使用的动态链接库、静态链接库或者静态导入库。
       jsconcpp 进行 JSON 解析的源码文件分布在 include/json、src/lib_json 下。其实 jsoncpp 源码并不多,为了方便产品管理,此处没必要将其编译为动态链接库或者静态导入库,所以我们选择使用静态链接库。
       jsoncpp 已经处理的很完善了,所有编译选项都已经配置好,打开makefiles/vs71/jsoncpp.sln 便可以开始编译。


四、jsoncpp 使用详解
       jsoncpp 主要包含三种类型的 class:Value、Reader、Writer。jsoncpp 中所有对象、类名都在 namespace Json 中,包含 json.h 即可。
      Json::Value 只能处理 ANSI 类型的字符串,如果 C++ 程序是用 Unicode 编码的,最好加一个 Adapt 类来适配。


1、Value
     Json::Value 是jsoncpp 中最基本、最重要的类,用于表示各种类型的对象,jsoncpp 支持的对象类型可见 Json::ValueType 枚举值。


可如下是用 Json::Value 类:
Json::Value json_temp;      // 临时对象,供如下代码使用
json_temp["name"] = Json::Value("huchao");
json_temp["age"] = Json::Value(26);


Json::Value root;  // 表示整个 json 对象
root["key_string"] = Json::Value("value_string"); // 新建一个 Key(名为:key_string),赋予字符串值:"value_string"。
root["key_number"] = Json::Value(12345);          // 新建一个 Key(名为:key_number),赋予数值:12345。
root["key_boolean"] = Json::Value(false);            // 新建一个 Key(名为:key_boolean),赋予bool值:false。
root["key_double"] = Json::Value(12.345);          // 新建一个 Key(名为:key_double),赋予 double 值:12.345。
root["key_object"] = Json_temp;                          // 新建一个 Key(名为:key_object),赋予 json::Value 对象值。
root["key_array"].append("array_string");           // 新建一个 Key(名为:key_array),类型为数组,对第一个元素赋值为字符串:"array_string"。
root["key_array"].append(1234);                           // 为数组 key_array 赋值,对第二个元素赋值为:1234。
Json::ValueType type = root.type();                       // 获得 root 的类型,此处为 objectValue 类型。


       注:跟C++ 不同,JavaScript 数组可以为任意类型的值,所以 jsoncpp 也可以。
       如上几个用法已经可以满足绝大部分 json 应用了,当然 jsoncpp 还有一些其他同能,比如说设置注释、比较 json 大小、交换 json 对象等,都很容易使用,大家自己尝试吧。


2、Writer
      如上说了 Json::Value 的使用方式,现在到了该查看刚才赋值内容的时候了,查看 json 内容,使用 Writer 类即可。
     Jsoncpp 的 Json::Writer 类是一个纯虚类,并不能直接使用。在此我们使用 Json::Writer 的子类:Json::FastWriter、Json::StyledWriter、Json::StyledStreamWriter。


顾名思义,用 Json::FastWriter 来处理 json 应该是最快的,下面我们来试试。


Json::FastWriter fast_writer;
std::cout << fast_writer.write(root) << std::endl;
输出结果为:
{"key_array":["array_string",1234],"key_boolean":false,"key_double":12.3450,"key_number":12345,"key_object":{"age":26,"name":"huchao"},"key_string":"value_string"}


再次顾名思义,用 Json::StyledWriter 是格式化后的 json,下面我们来看看 Json::StyledWriter 是怎样格式化的。
Json::StyledWriter styled_writer;
std::cout << styled_writer.write(root) << std::endl;
输出结果为:
{
   "key_array" : [ "array_string", 1234 ],
   "key_boolean" : false,
   "key_double" : 12.3450,
   "key_number" : 12345,
   "key_object" : {
         "age" : 26,
         "name" : "huchao"
   },
   "key_string" : "value_string"
}


3、Reader
    Json::Reader 是用于读取的,说的确切点,是用于将字符串转换为 Json::Value 对象的,下面我们来看个简单的例子。
    Json::Reader reader;
    Json::Value json_object;
    const char* json_document = "{\"age\" : 26,\"name\" : \"huchao\"}";
    if (!reader.parse(json_document, json_object))
          return 0;


    std::cout << json_object["name"] << std::endl;
    std::cout << json_object["age"] << std::endl;
输出结果为:
"huchao"
26
可见,上述代码已经解析出了 json 字符串。
========

C++ 解析Json——jsoncpp

http://www.cppblog.com/wanghaiguang/archive/2013/12/26/205020.html
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,和xml类似,本文主要对VS2008中使用Jsoncpp解析json的方法做一下记录。
Jsoncpp是个跨平台的开源库,下载地址:http://sourceforge.net/projects/jsoncpp/,我下载的是v0.5.0,压缩包大约104K。


方法一:使用Jsoncpp生成的lib文件
      解压上面下载的Jsoncpp文件,在jsoncpp-src-0.5.0/makefiles/vs71目录里找到jsoncpp.sln,用VS2008版本编译,默认生成静态链接库。 在工程中引用,只需要包含include/json下的头文件及生成的.lib文件即可。
      如何包含lib文件:在.cpp文件中#pragma comment(lib."json_vc71_libmt.lib"),在工程属性中Linker下Input中Additional Dependencies写入lib文件名字(Release下为json_vc71_libmt.lib,Debug为json_vc71_libmtd.lib)


注意:Jsoncpp的lib工程编译选项要和VS工程中的编译选项保持一致。如lib文件工程编译选项为MT(或MTd),VS工程中也要选择MT(或MTd),否则会出现编译错误问题,debug和release下生成的lib文件名字不同,注意不要看错了,当成一个文件来使用(我就犯了这


个错误)。


方法二:使用Jsoncpp包中的.cpp和.h文件
      解压上面下载的Jsoncpp文件,把jsoncpp-src-0.5.0文件拷贝到工程目录下,将jsoncpp-src-0.5.0\jsoncpp-src-0.5.0\include\json和jsoncpp-src-0.5.0\jsoncpp-src-0.5.0\src\lib_json目录里的文件包含到VS工程中,在VS工程的属性C/C++下General中


Additional Include Directories包含头文件目录.\jsoncpp-src-0.5.0\include。在使用的cpp文件中包含json头文件即可,如:#include "json/json.h"。将json_reader.cpp、json_value.cpp和json_writer.cpp三个文件的Precompiled Header属性设置为Not Using 


Precompiled Headers,否则编译会出现错误。


jsoncpp 使用详解
jsoncpp 主要包含三种类型的 class:Value、Reader、Writer。jsoncpp 中所有对象、类名都在 namespace Json 中,包含 json.h 即可。
Json::Value 只能处理 ANSI 类型的字符串,如果 C++ 程序是用 Unicode 编码的,最好加一个 Adapt 类来适配。


下面是从网上找的代码示例:
1. 从字符串解析json
    const char* str = "{\"uploadid\": \"UP000000\",\"code\": 100,\"msg\": \"\",\"files\": \"\"}";  


    Json::Reader reader;  
    Json::Value root;  
    if (reader.parse(str, root))  // reader将Json字符串解析到root,root将包含Json里所有子元素  
    {  
        std::string upload_id = root["uploadid"].asString();  // 访问节点,upload_id = "UP000000"  
        int code = root["code"].asInt();    // 访问节点,code = 100 
    }  
2. 从文件解析json
int ReadJsonFromFile(const char* filename)  
{  
    Json::Reader reader;// 解析json用Json::Reader   
    Json::Value root; // Json::Value是一种很重要的类型,可以代表任意类型。如int, string, object, array         


    std::ifstream is;  
    is.open (filename, std::ios::binary );    
    if (reader.parse(is, root, FALSE))  
    {  
        std::string code;  
        if (!root["files"].isNull())  // 访问节点,Access an object value by name, create a null member if it does not exist.  
            code = root["uploadid"].asString();  
        
        code = root.get("uploadid", "null").asString();// 访问节点,Return the member named key if it exist, defaultValue otherwise.    


        int file_size = root["files"].size();  // 得到"files"的数组个数  
        for(int i = 0; i < file_size; ++i)  // 遍历数组  
        {  
            Json::Value val_image = root["files"][i]["images"];  
            int image_size = val_image.size();  
            for(int j = 0; j < image_size; ++j)  
            {  
                std::string type = val_image[j]["type"].asString();  
                std::string url  = val_image[j]["url"].asString(); 
                printf("type : %s, url : %s \n", type.c_str(), url.c_str());
            }  
        }  
    }  
    is.close();  


    return 0;  

3. 向文件中插入json
void WriteJsonData(const char* filename)
{
    Json::Reader reader;  
    Json::Value root; // Json::Value是一种很重要的类型,可以代表任意类型。如int, string, object, array        


    std::ifstream is;  
    is.open (filename, std::ios::binary );    
    if (reader.parse(is, root))  
    {  
        Json::Value arrayObj;   // 构建对象  
        Json::Value new_item, new_item1;  
        new_item["date"] = "2011-11-11";  
        new_item1["time"] = "11:11:11";  
        arrayObj.append(new_item);  // 插入数组成员  
        arrayObj.append(new_item1); // 插入数组成员  
        int file_size = root["files"].size();  
        for(int i = 0; i < file_size; ++i)  
            root["files"][i]["exifs"] = arrayObj;   // 插入原json中 
        std::string out = root.toStyledString();  
        // 输出无格式json字符串  
        Json::FastWriter writer;  
        std::string strWrite = writer.write(root);
        std::ofstream ofs;
        ofs.open("test_write.json");
        ofs << strWrite;
        ofs.close();
    }  


    is.close();  
}


下面是我写的使用Jsoncpp生成lib文件的工程示例:Jsoncpp测试代码,使用VS2008编译通过。
========

使用JsonCPP解析JSON数据(VC++)

http://blog.youkuaiyun.com/hgy2011/article/details/7581673


首先你必须在http://sourceforge.net/projects/jsoncpp/files/jsoncpp/下载jsoncpp的源代码(.cpp/.h/.inl)包含到过程中如下图:惊讶


测试源代码:[testjson.cpp]
#include "stdafx.h"
#include<iostream>
#include <string>
#include "json.h" //包含头文件


using namespace std;
using namespace Json;


void readJson();
void writeJson();


int main(int argc, char** argv) {
readJson();




    cout << "---------------------------------------------" << endl;




writeJson();


return 0;
}
 
//解析JSON数据
void readJson() 
{
std::string strValue = "{\"name\":\"json\",\"array\":[{\"cpp\":\"jsoncpp\"},{\"java\":\"jsoninjava\"},{\"php\":\"support\"}]}";




Json::Reader reader;
Json::Value value;




if (reader.parse(strValue, value))
{
std::string out = value["name"].asString();
std::cout << out << std::endl;
const Json::Value arrayObj = value["array"];
for (unsigned int i = 0; i < arrayObj.size(); i++)
{
if (!arrayObj[i].isMember("cpp")) 
continue;
out = arrayObj[i]["cpp"].asString();
std::cout << out;
if (i != (arrayObj.size() - 1))
std::cout << std::endl;
}
}
}


//生成JSON格式数据
void writeJson() 
{
Json::Value root;
Json::Value arrayObj;
Json::Value item;




item["cpp"] = "jsoncpp";
item["java"] = "jsoninjava";
item["php"] = "support";
arrayObj.append(item);




root["name"] = "json";
root["array"] = arrayObj;




root.toStyledString();
std::string out = root.toStyledString();
std::cout << out << std::endl;
}


输出结果:


更多内容请参考:http://jsoncpp.sourceforge.net/
========

VC++获取网页回来的JSON数据



2、在VC++中


bool CQuickSearchDlg::getSearchJson(const TCHAR * keyword, TCHAR * json)
{
    wchar_t isonUrl[200] = _T("http://sg1.api.bing.com/qsonhs.aspx?q=设计");
    CInternetSession cSession;
    CHttpFile *cFile;
    char sRecived[1024] = {0};
    CString szAllData = _T("");


    try
    {
        cFile = (CHttpFile *)cSession.OpenURL(isonUrl);
    }
    catch(CInternetException * m_pException)
    {
        cFile = NULL;
        m_pException->m_dwError;
        m_pException->Delete();
        cSession.Close();
        AfxmessageBox(_T("CInternetException"));
        return false;
    }


    DWORD dwStatusCode;
    cFile->QueryInfoStatusCode(dwStatusCode);
    if(dwStatusCode == HTTP_STATUS_OK)
    {
        while(cFile->ReadString((LPTSTR)sRecived, 1024) != NULL)
            szAllData += sRecived;
        int a = 0;
    }
    else
    {
        MessageBox(_T("请求失败。。。。"));
    }
    cFile->Close();
    delete cFile;
    cSession.Close();


    return true;
}
获取到的szAllData数据却是:{"AS":{"Query":"设计","FullResults":0}}
这是哪里出问题了呢? vc++ json CInternetSession OpenURL 
转为UTF-8编码就可以了
例如“设计”的UTF-8码是E8AEBE E8AEA1


http://sg1.api.bing.com/qsonhs.aspx?q=%E8%AE%BE%E8%AE%A1


已知char utf[10]里面存储了以UTF-8编码存储的字符,如何获得相应的十六进制字符编码?
        ……


char utf[10];
char utff[30];
for (int n = 0; n < strlen(utf); n ++)
{
  sprintf(&utff[n * 3], "%%%02x", utf[n]);
}
========
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值