现在的位置: 首页 > 综合 > 正文

基于dic.cn webapi的linux终端词典工具

2013年08月14日 ⁄ 综合 ⁄ 共 2818字 ⁄ 字号 评论关闭

基于dic.cn webapilinux终端词典工具

 

一、由来

因工作和学习需要,需要在linux terminal上使用英汉词典,编写本程序。

工程下载:http://alionkun.download.csdn.net/

程序使用方法:

安装:将d拷贝到/usr/bin目录下:cp d /usr/bin

使用:d lion

 

源文件编译:

gcc -std=c99 -o d d.c

 

二、webapi of dict.cn

 

首先,了解dict.cnwebapi。直接实验,上图给结果,不解释了。

在浏览器中输入:http://dict.cn/ws.php?q=hello

得到:

输入:http://dict.cn/ws.php?q=balabala

得到:

 

三、使用socket 实现http并解析xml文件

 

由于程序需求比较简单,只是以url的方式向服务器请求xml文件,所以直接使用socketTCP的基础上实现http;值得注意的是,web上的数据编码可能不同于linux平台的编码,故存在转码的需求。

照例,我们直接上代码。

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <netdb.h>

#include <iconv.h>

#include <errno.h>

 

// convert gbk to utf-8

int code_convert(char *from,int fromlen, char *to, int tolen)

{

iconv_t cd;

cd=iconv_open("utf-8","gbk");

if(cd==0)

{

printf("iconv_open failed./n");

return -1;

}

 

char *pfrom=from;

char *pto=to;

// convert

if(iconv(cd, &pfrom, &fromlen, &pto, &tolen)==-1)

 

{

 

printf("iconv error. errorno=%d/n",errno);

return -1;

}

iconv_close(cd);

// out

return 0;

}

 

int main(int argc, char *argv[])

{

// check paramters.

// we can add more options here...

if(argc<2)

{

printf("syntax error./n");

return 0;

}

// get information fro "www.dict.cn"

// where provide a proper web api we need.

struct hostent *he;

if((he=gethostbyname("www.dict.cn"))==NULL)

{

printf("#can't get IP of www.dict.cn./n");

return -1;

}

// connect to server.

struct sockaddr_in server;

int fd;

if((fd=socket(AF_INET, SOCK_STREAM,0))== -1)

{

printf("#application error./n");

return 0;

}

server.sin_family=AF_INET;

server.sin_port=htons(80);

server.sin_addr=*((struct in_addr*)he->h_addr_list[0]);

if(connect(fd, (struct sockaddr*)&server, sizeof(struct sockaddr))==-1)

{

printf("#can't connect to www.dict.cn; check if your network is down./n");

return -1;

}

 

// send HTTP request with GET method.

char buf[1024*5]={0};

sprintf(buf,"GET /ws.php?q=%s HTTP/1.1/r/n%s%s%s%s%s",

argv[1],

"Accept: */*/r/n",

"Accept-Language: zh-cn/r/n",

"User-Agent:Mozilla/4.0/r/n",

"Host:dict.cn/r/n",

"Connection: Keep-Alive/r/n/r/n");

send(fd,buf,strlen(buf),0 );

// receive server responce.

recv(fd, buf,1024*5,0);

 

// analyse server responce string.

char result[1024*5]={0};

// code convertion.

if(0!=code_convert(buf+20,strlen(buf),result,1024*5))

return -1;

 

char *p;

// valid search ?

p=strstr(result,"<key>");

if(p)

p+=strlen("<key>");

else

{

printf("#zero result of %s/n",argv[1]);

printf("#suggest:/n");

p=result;

while(p=strstr(p,"<sugg>"))

{

p+=strlen("<sugg>");

printf("/t");

while(*p!='<')

{

printf("%c",*p++);

}

printf("/n");

 

}

printf("/n-------------------------------/n");

return 0;

}

printf("/x1b[32m");

while(*p!='<')

printf("%c",*p++);

printf("/n");

p=strstr(p,"<def>");

if(p)

p+=strlen("<def>");

while(*p!='<')

printf("%c",*p++);

 

printf("/n---------------------------------/n/x1b[0m");

 

return 0;

}

 

四、结语

由于各个版本的linux终端编码方式可能存在差异,所以可以根据需要改变源程序中的转码子程序,确保程序运行时不出现乱码。

正如你所想到的,可以为程序提供更多的options来扩展其功能。

 

抱歉!评论已关闭.