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 }
View Code

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM