您的位置:首页 > 运维架构 > Linux

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

2011-05-31 15:56 555 查看

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

一、由来

因工作和学习需要,需要在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.cn的webapi。直接实验,上图给结果,不解释了。
在浏览器中输入:http://dict.cn/ws.php?q=hello
得到:



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



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

由于程序需求比较简单,只是以url的方式向服务器请求xml文件,所以直接使用socket在TCP的基础上实现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来扩展其功能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: