C++ Builder 使用 JsonCpp 解析json格式数据方法( 支持 UNICODE (UTF-16) / UTF-8 )

JsonCpp 是一个比较著名的JSON (JavaScript Object Notation) 开发库,官方网站:http://jsoncpp.sourceforge.net/ ,JsonCpp 的最新版本 0.5.0,官方下载地址:http://sourceforge.net/projects/jsoncpp/files/ 。

官方版本只提供了 Visual C++ 的编译和使用方法,C++ Builder 编译会报语法错误,经过测试,发现做如下改动,可以在 C++ Builder 里面编译通过:

① include\json\value.h 第 886 行开始位置的 ValueIteratorBase 类的几个构造函数移动到这个类的后面,移动之后的位置在第 938 行开始的位置,只是把位置移动到这里,没有修改代码内容。构造函数写在前面就编译不通过,写在后面就能编译通过,至于为什么,还没研究明白,因为任何地方的语法都根本就没有错误。

② src\lib_json\json_reader.cpp 第 9 行:添加一行 #include <stdio.h> 。也许是 VC 会在项目里面默认就包含这个头文件,BCB 需要在代码里面添加包含 stdio.h 才能调用里面的函数。

使用方法:

第一种方法:先生成 .lib 库文件,应用程序链接这个库文件。
编译、生成 .lib 库文件的方法:创建一个生成静态库的项目,只需要把 jsoncpp-src-0.5.0\src\lib_json 文件夹里面的 3 个 .cpp 文件:
json_reader.cpp
json_value.cpp
json_writer.cpp 

加入进来,编译,生成的 .lib 文件就可以使用了。


第二种方法:直接把 jsoncpp-src-0.5.0\src\lib_json 文件夹里面的 3 个 .cpp 文件:
json_reader.cpp
json_value.cpp
json_writer.cpp 

加入应用程序项目文件。

下面主要是介绍 UNICODE 支持。

C++ Builder 2009 之后支持 UNICODE,之前版本,比如 BCB 6.0 不支持 UNICODE。
C++ Builder 2009 之后的版本,可以用 UTF8String 来让 JsonCpp 开发库支持 UNICODE。
早期版本的 BCB 不支持 UNICODE,只能用 AnsiString 代替后面文章的 UTF8String,当然,程序也就不支持 UNICODE 了,所有的处理都是 ANSI 编码了。

以下关于 UNICODE 的支持,适用于 C++ Builder 2009 之后的版本。
UNICODE 字符串转换的规律:std::string <= 用.c_str() => UTF8String <= 直接赋值 => UnicodeString 或 L"字符串" - http://www.cppfans.com/
UTF8String 可以和 UnicodeString 之间相互赋值,因为他们都是 UNICODE,只是编码方式不同,一个是 UTF-8,另一个是 UTF-16。
UTF8String 可以和 std::string 之间,用 .c_str() 转换为另一个,而 UnicodeString 和 std::string 之间转换,必须中间经过 UTF8String。
例如:

UTF8String u8 = L"UNICODE字符串"; // 引号前面加 L 表示使用 UNICODE
UnicodeString u16 = L"UNICODE字符串"; // 引号前面加 L 表示使用 UNICODE
std::string ss; // 不要直接给 std::string 赋值,因为这个类型不能直接支持 UNICODE,需要用 UTF-8 

u8=u16; // UTF-8 和 UNICODE (UTF-16) 之间可以直接赋值
ss=u8.c_str(); // 用 UTF8String 的 .c_str() 转成 std::string
// http://www.cppfans.com/
u8=ss.c_str(); // 用 std::string 的 .c_str() 转成 UTF8String
u16=u8; // UNICODE (UTF-16) 和 UTF-8 之间可以直接赋值

掌握了这个规律,就可以让 JsonCpp 支持 UNICODE。

Json::Value root;

root["name"] = "Mr. Chen"; // 英文的 UTF-8 编码和 ANSI 编码相同,这样写没有问题
root[UTF8String(L"姓名").c_str()] = UTF8String(L"陈先生").c_str(); // 汉字必须说明 UTF-8

UTF8String name = root["name"].asCString(); // asCString() 可直接转成 UTF8String
UTF8String 姓名 = root[UTF8String(L"姓名").c_str()].asCString();
// http://www.cppfans.com/
Memo2->Lines->Add(L"name: " + name); // UTF-8 也是 UNICODE,这样写没问题
Memo2->Lines->Add(L"姓名: " + 姓名); // UTF-8 也是 UNICODE,这样写没问题

解析和读取数据:

void __fastcall TFormTestJson::ButtonGetValueClick(TObject *Sender)
{
   UTF8String txt = Memo1->Text; // 使用 UTF8String 来支持 UNICODE 
   Json::Reader reader;
   Json::Value root;
   if(!reader.parse(txt.c_str(),root)) // 需要用.c_str()转换 - http://www.cppfans.com/
   {
       Memo2->Lines->Add(L"结构错误");
       return;
   }

  Memo2->Lines->Clear();
  UTF8String s = root["strval"].asCString(); // asCString() 可直接给 UTF8String 赋值
  Memo2->Lines->Add(L"strval="+s); // UNICODE / UTF8 是支持世界各国语言的

  UTF8String key = L"整数值";
  s = root[key.c_str()].asCString();
  Memo2->Lines->Add(L"整数值="+s);

  int n = root["arrval"].size();
  for(int i=0; i<n; i++)
  {
     s = root["arrval"][i].asCString();
     Memo2->Lines->Add(L"arrval的第"+String(i)+L"个数是"+s);
  }
}

生成 Json 文件:

void __fastcall TFormTestJson::ButtonSaveFileClick(TObject *Sender)
{
  Json::Value root;
  UTF8String key, val; // 使用 UTF8String 来支持 UNICODE

  key = L"name";
  val = L"JSON测试程序, 支持UNICODE哦";
  root[key.c_str()] = val.c_str();

  key = L"desc";
  val = L"Copyright © Victor Chen, http://www.cppfans.com/";
  root[key.c_str()] = val.c_str();

  key = L"字符串值";
  val = L"中文한국어Tiếng Việt"; // UNICODE / UTF-8 支持世界各国语言混合文本
  root[key.c_str()] = val.c_str();

  UTF8String txt = root.toStyledString().c_str();
  Memo2->Text = txt;

  UnicodeString fname = ExtractFilePath(Application->ExeName)+L"Test.txt";
  int hFile = FileCreate(fname);
  if(hFile>=0)
  {
    if(RadioButtonUNICODE->Checked)
    {
      Memo2->Lines->Add(L"生成UNICODE文件");
      UnicodeString us = txt;
      FileWrite(hFile,"\xFF\xFE",2); // UNICODE
      FileWrite(hFile,us.c_str(),us.Length()*sizeof(wchar_t));
    }
    else
    {
      Memo2->Lines->Add(L"生成UTF8文件");
      FileWrite(hFile,"\xEF\xBB\xBF",3); // UTF8
      FileWrite(hFile,txt.c_str(),txt.Length());
    }
    FileClose(hFile);
    Memo2->Lines->Add(L"已经保存到UTF8文件: "+fname);
  }
}


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值