C++中使用Curl和JsonCpp调用有道翻译API实现在线翻译
使用C++开发一个在线翻译工具,这个想法在我大脑中过了好几遍了,所以就搜了下资料,得知网络上有很多翻译API,这里我选择我平时使用较多的有道翻译API进行在线翻译工具开发的练习。翻译API返回的结果常见的有两种:xml和json格式,本文选择使用json数据来实现Berlin版本的在线翻译工具。
开发环境:Ubuntu12.04 + GCC4.7
一、 有道翻译API
API 地址:http://fanyi.youdao.com/openapi
这里我选择了数据调用接口key的申请,填入相关信息,然后系统会提供API Key和Keyfrom字段给你,同时会发送一份包含这2项的邮件到你所填写的邮箱。
有道翻译API的数据接口如下:
http://fanyi.youdao.com/openapi.do?keyfrom=<keyfrom>&key=<key>&type=data&doctype=<doctype>&version=1.1&q=要翻译的文本
版本:1.1,请求方式:get,编码方式:utf-8
主要功能:中英互译,同时获得有道翻译结果和有道词典结果(可能没有)
参数说明:
type - 返回结果的类型,固定为data
doctype - 返回结果的数据格式,xml或json或jsonp
version - 版本,当前最新版本为1.1
q - 要翻译的文本,不能超过200个字符,需要使用utf-8编码
errorCode:
0 - 正常
20 - 要翻译的文本过长
30 - 无法进行有效的翻译
40 - 不支持的语言类型
50 - 无效的key
二、 Curl和JsonCpp的安装
2.1 Curl的安装
Curl工程主页:http://curl.haxx.se/, 目前最新版本是curl-7.34.0,下载解压后进入curl-7.34.0目录,用如下命令安装:
1 cd $CURL_HOME 2 mkdir build 3 cd build 4 cmake .. 5 make
2.2 JsonCpp的安装
JsonCpp工程主页:http://jsoncpp.sourceforge.net/,目前的最新版本是jsoncpp-src-0.5.0,下载解压后进入jsoncpp-src-0.5.0,使用Scons进行安装,Scons是一个Python编译系统,没有安装的童鞋需要先安装Scons,如下:
1 sudo apt-get install scons
Scons安装好之后就可以编译JsonCpp了,使用如下命令:
1 scons platform=linux-gcc
好了,JsonCpp已经成功安装了,为了后面程序编译链接过程中方便,我在JsonCpp路径下的libs文件夹中设置了一个软连接,如下:
1 ln -s libjson_linux-gcc-4.7_libmt.a libjson_linux-gcc.a
三、 在线翻译工具
直接贴代码:
1 /* 2 Filename: translate.cc 3 Author: BerlinSun 4 */ 5 #include <iostream> 6 #include "curl/curl.h" 7 #include "json/json.h" 8 9 using namespace std; 10 11 void usage() 12 { 13 cout << "Usage: translate word_you_want_to_translate" << endl; 14 } 15 16 int writer(char *data, size_t size, size_t nmemb, string *writerData) 17 { 18 if (writerData == NULL) 19 return 0; 20 int len = size*nmemb; 21 writerData->append(data, len); 22 return len; 23 } 24 25 int main(int argc, char *argv[]) 26 { 27 if(argc < 2) 28 { 29 usage(); 30 exit(0); 31 } 32 string buffer; 33 string translate_url = "http://fanyi.youdao.com/openapi.do?keyfrom=xxxxxx&key=xxxxxx&type=data&doctype=json&version=1.1&q="; 34 translate_url += argv[1]; 35 CURL * curl; 36 CURLcode res; 37 curl = curl_easy_init(); 38 if (curl) 39 { 40 curl_easy_setopt(curl, CURLOPT_URL, translate_url.c_str()); 41 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer); 42 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer); 43 res = curl_easy_perform(curl); 44 curl_easy_cleanup(curl); 45 } 46 if (buffer.empty()) 47 { 48 cout << "The server return NULL!" << endl; 49 exit(0); 50 } 51 52 Json::Value root; 53 Json::Reader reader; 54 bool parsingSuccessful = reader.parse(buffer, root); 55 56 if (!parsingSuccessful) 57 { 58 cout << "Failed to parse the data!" << endl; 59 exit(0); 60 } 61 62 const Json::Value basic = root["basic"]; 63 const Json::Value phonetic = basic["phonetic"]; 64 const Json::Value explains = basic["explains"]; 65 cout << "Provided by Youdao dictionary!" << endl; 66 cout << "-----------------------------" << endl; 67 cout << argv[1] << "\t英[" << phonetic.asString() << "]" << endl; 68 69 for(int i = 0; i < explains.size(); ++i) 70 cout << explains[i].asString() << endl; 71 72 return 0; 73 }
PS:代码中红色加粗的部分就是你所申请到的key和keyfrom字段。
CMake文件如下:
1 project(test) 2 cmake_minimum_required(VERSION 2.6) 3 4 include_directories($ENV{JSONCPP_HOME}/include $ENV{CURL_HOME}/include) 5 link_directories($ENV{JSONCPP_HOME}/libs/ $ENV{CURL_HOME}/build/lib) 6 add_definitions(-std=c++0x) 7 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") 8 9 set(source 10 translate.cc) 11 add_executable(translate ${source}) 12 target_link_libraries(translate json_linux-gcc) 13 target_link_libraries(translate curl)
程序执行效果如下:
=====================================================================
补充:
之前实现这个工具的时候没有考虑汉译英,所以并没有对汉语进行测试,感谢yough90提出汉语没法翻译的问题,这个问题其实很好理解,编码问题,中文和英文使用不同的编码方式,解决方案也比较简单,libcurl提供了专门用于编码的方法:
1 char *curl_easy_escape( CURL * curl , char * url , int length );
在我们检测到我们传入的参数有非ASCII编码的时候,我们调用该函数对其进行转换:
1 if ((*argv[1]&0x80) != 0) 2 { 3 type = 0; 4 char *encode_word = curl_easy_escape(curl, argv[1], 0); 5 translate_url += encode_word; 6 } else { 7 type = 1; 8 translate_url += argv[1]; 9 }
由于后面显示格式会有所不同,所以我加入一个type用来记住翻译类型,好了,修改后的代码如下:
1 #include <iostream> 2 #include "curl/curl.h" 3 #include "json/json.h" 4 5 using namespace std; 6 7 void usage() 8 { 9 cout << "Usage: translate word_you_want_to_translate" << endl; 10 } 11 12 int writer(char *data, size_t size, size_t nmemb, string *writerData) 13 { 14 if (writerData == NULL) 15 return 0; 16 int len = size*nmemb; 17 writerData->append(data, len); 18 return len; 19 } 20 21 int main(int argc, char *argv[]) 22 { 23 if(argc < 2) 24 { 25 usage(); 26 exit(0); 27 } 28 string buffer; 29 string translate_url = "http://fanyi.youdao.com/openapi.do?keyfrom=xxxxxxxx&key=xxxxxxxx&type=data&doctype=json&version=1.1&q="; 30 CURL * curl; 31 CURLcode res; 32 curl = curl_easy_init(); 33 34 int type; 35 36 if ((*argv[1]&0x80) != 0) 37 { 38 type = 0; 39 char *encode_word = curl_easy_escape(curl, argv[1], 0); 40 translate_url += encode_word; 41 } else { 42 type = 1; 43 translate_url += argv[1]; 44 } 45 46 if (curl) 47 { 48 curl_easy_setopt(curl, CURLOPT_URL, translate_url.c_str()); 49 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer); 50 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer); 51 res = curl_easy_perform(curl); 52 curl_easy_cleanup(curl); 53 } 54 if (buffer.empty()) 55 { 56 cout << "The server return NULL!" << endl; 57 exit(0); 58 } 59 60 Json::Value root; 61 Json::Reader reader; 62 bool parsingSuccessful = reader.parse(buffer, root); 63 64 if (!parsingSuccessful) 65 { 66 cout << "Failed to parse the data!" << endl; 67 exit(0); 68 } 69 70 if (root["errorCode"] != 0) 71 { 72 cout << "errorCode: " << root["errorCode"] << endl; 73 exit(0); 74 } 75 const Json::Value basic = root["basic"]; 76 const Json::Value phonetic = basic["phonetic"]; 77 const Json::Value explains = basic["explains"]; 78 cout << "Provided by Youdao dictionary!" << endl; 79 cout << "-----------------------------" << endl; 80 const char *prefix = type == 0 ? "[" : "英["; 81 cout << argv[1] << "\t" << prefix << phonetic.asString() << "]" << endl; 82 83 for(int i = 0; i < explains.size(); ++i) 84 cout << explains[i].asString() << endl; 85 86 return 0; 87 }
这里,对之前博友提出的没有验证errorCode的问题也一并修复了!汉语翻译结果如下:
谢谢大家的阅读!
语音辞典功能见这里:http://www.cnblogs.com/berlin-sun/p/OnlineDictionary.html
作者:
薛定谔の喵
出处:
http://www.cnblogs.com/berlin-sun/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。