基于linux下的在线云词典项目

云词典项目流程图

执行效果参考

服务器

#include <stdio.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <signal.h>
#include <sqlite3.h>
#include <sys/wait.h>
#include <poll.h>
#include <time.h>
#include "head.h"

char *err=NULL;
int zhuce(MSG xie,int ept,sqlite3 *db,struct sockaddr_in addr);//注册
int denglu(MSG xie,int ept,sqlite3 *db);//登录
int danci(MSG xie,int ept,sqlite3 *db);//查询
int lishi(MSG xie,int ept,sqlite3 *db);//历史记录

int main(int argc, char const *argv[])
{
    if (argc<2)
    {
        printf("usage:<port>");
        return -1;
    }
    //打开或创建数据库
    sqlite3 *db=NULL;
    if (sqlite3_open("./cidian.db", &db)!=SQLITE_OK)
    {
        printf("sqlite3_open err:%s\n",sqlite3_errmsg(db));
        return -1;
    }
    printf("词典数据库打开成功。\n");
    //创建套接字 用于链接
    int sock=socket(AF_INET,SOCK_STREAM,0);
    if (sock<0)
    {
        perror("socket err");
        return -1;
    }
    printf("sock:%d\n",sock);
    //绑定 
    struct sockaddr_in add,addr;
    socklen_t len=sizeof(addr);
    add.sin_family=AF_INET;  //协议族AF_INET
    add.sin_port=htons(atoi(argv[1]));    //端口
#if 1
    add.sin_addr.s_addr=inet_addr("0.0.0.0");//ip地址转换为32位无符号长整数型数
#else
    add.sin_addr.s_addr=INADDR_ANY;
#endif
    if (bind(sock,(struct sockaddr *)&add,sizeof(add)) < 0 )
    {
        perror("bind err.");
        return -1;
    }
    printf("bind success\n");
    //监听
    if ( listen(sock,6) < 0 )
    {
        perror("listen err");
        return -1;
    }
    printf("listen success\n");
    //引入poll 创建表
    int last=-1;
    struct pollfd pofd[128];

    //填数据
    pofd[++last].fd=sock;
    pofd[last].events=POLLIN;

    //协议
    MSG xie;

    while (1)
    {
        //监测
        if (poll(pofd,last+1,-1) < 0)
        {
            perror("poll err.");
            return -1;
        }
        //判断
        for (int  i = 0; i <= last; i++)
        {
            if (pofd[i].revents == POLLIN)
            {
                if (pofd[i].fd == sock )//判断链接
                {
                    int ept=accept(sock,(struct sockaddr *)&addr,&len);
                    if (ept < 0)
                    {
                        perror("accept err.");
                        return -1;
                    }
                    printf("accept:%d ",ept);
                    printf("ip:%s port:%d\n",inet_ntoa(addr.sin_addr),ntohs(addr.sin_port));
                    pofd[++last].fd=ept;
                    pofd[last].events=POLLIN;
                }
                else//接收
                {
                    int ret=recv(pofd[i].fd,&xie,sizeof(xie),0);
                    if (ret<0)
                    {
                        perror("recv err.");
                        return -1;
                    }
                    else if(ret==0)//有客户端退出
                    {
                        printf("ip:%s port:%d 已退出\n",inet_ntoa(addr.sin_addr),ntohs(addr.sin_port));
                        close(pofd[i].fd);
                        pofd[i--]=pofd[last--];//删除退出客户端
                    }
                    else//接收到数据
                    {  
                        switch (xie.type)
                        {
                            case R :zhuce(xie,pofd[i].fd,db,addr);break;//注册
                            case L :denglu(xie,pofd[i].fd,db);break; //登录
                            case Q :danci(xie,pofd[i].fd,db);break;  //单词查询
                            case H :lishi(xie,pofd[i].fd,db);break;  //历史记录
                            default:printf("输入错误啦\n");break;
                        }
                    }
                }
            } 
        }
    }
    return 0;
}

//注册
int zhuce(MSG xie,int ept,sqlite3 *db,struct sockaddr_in addr)
{
    char **result=NULL,sql[128]={0};
    int hang,lie,k=0;
    sqlite3_get_table(db,"select * from zhuce;",&result,&hang,&lie,&err);//查询表中数据
    for (int i = 0; i <= hang; i++)//遍历行
    {
        if (strcmp(xie.name,result[k])==0)//判断表中帐号是否存在
        {
            strcpy(xie.data,"already exist!!!");
            send(ept,&xie,sizeof(xie),0);
            return 0;
        }
        else
        {
            k+=2;//k移到下一行
        }
    }
    if (strncmp(xie.data,"already exist!!!",17)!=0)//表中帐号不存在注册
    {
        sprintf(sql,"insert into zhuce values(\"%s\",\"%s\");",xie.name,xie.data);//拼接指令
        if(sqlite3_exec(db,sql,NULL,NULL,&err)!=SQLITE_OK)//往表中写入内容
        {
            printf("insert zhuce err:%s\n",err);
            return -1;
        }
        //通知用户注册成功
        strcpy(xie.data,"OK");
        send(ept,&xie,sizeof(xie),0);
        printf("ip:%s port:%d name:%s 注册成功!\n",inet_ntoa(addr.sin_addr),ntohs(addr.sin_port),xie.name); 
    }
    return 0;
}

//登录
int denglu(MSG xie,int ept,sqlite3 *db)
{
    char **result=NULL;
    char sql[128]={0};
    int hang,lie,k=0;
    sqlite3_get_table(db,"select * from zhuce;",&result,&hang,&lie,&err);//查询表中数据
    for (int i = 0; i <= hang; i++)
    {
        if ((strcmp(xie.name,result[k])==0)&&(strcmp(xie.data,result[k+1])==0))
        {
            
            strcpy(xie.data,"OK");
            send(ept,&xie,sizeof(xie),0);
            return 0;
        }
        k+=2;//k移到下一行
    } 
    strcpy(xie.data,"err.");
    send(ept,&xie,sizeof(xie),0); 
    return 0; 
}
//查询单词
int danci(MSG xie,int ept,sqlite3 *db)
{
    char **result=NULL,sql[128]={0};
    int hang,lie,k=0,n=0;
    sqlite3_get_table(db,"select * from cidian;",&result,&hang,&lie,&err);//查询表中数据
    for (int i = 0; i <=hang; i++)
    {
        if (strcmp(xie.data,result[k])==0)//判断单词是否存在
        {
            //往历史记录表中写入时间
            char buf[128];
            time_t tv;
            struct tm *timer;
            tv = time(&tv);
            timer = localtime(&tv);
            strftime(buf,sizeof(buf),"%Y-%m-%d %H:%M:%S", timer);
            sprintf(sql,"insert into lishi values(\"%s\",\"%s\",\"%s\");",xie.name,buf,xie.data);//拼接指令
            if(sqlite3_exec(db,sql,NULL,NULL,&err)!=SQLITE_OK)//写入数据库内容
            {
                printf("insert lishi err:%s\n",err);
                return -1;
            }
            //发送释义并退出
            strcpy(xie.data,result[++k]);
            send(ept,&xie,sizeof(xie),0);
            return 0;
        }
        else
        {
            for (int j = 0; j < lie; j++)//不存在k移到下一行
            {
                k++;
            }
        }
    }
    //没有给客户端提示
    strcpy(xie.data,"没有收录!");
    send(ept,&xie,sizeof(xie),0);
    return 0;
}
//查询历史
int lishi(MSG xie,int ept,sqlite3 *db)
{
    char **result=NULL,sql[128]={0};
    int hang,lie,k=0,l=0;
    strcpy(sql,"select * from lishi;");
    sqlite3_get_table(db,sql,&result,&hang,&lie,&err);//查询表中数据
    for (int i = 0; i <=hang; i++)
    {
        
        if (strcmp(xie.name,result[k])==0)//根据帐号查找历史记录
        {
            sprintf(xie.data,"%s : %s",result[k+1],result[k+2]);//result[++k],result[++k]有可能造成内容相同!!
            send(ept,&xie,sizeof(xie),0);
            l=1;//用作判断是否有记录
        }
        k+=3;//不同k移到下一行
    }
    //提示发送结束或没有
    if (l==1)
    {
        strcpy(xie.data,"OK"); 
        send(ept,&xie,sizeof(xie),0);
    }
    else
    {
        l=0;
        strcpy(xie.data,"无历史记录!");
        send(ept,&xie,sizeof(xie),0);
    }
    return 0;
}

客户端

#include <stdio.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "head.h"

char name[128]={0};
void caidan1();//一级菜单
void caidan2();//二级菜单
int zhuce(MSG xie,int sock);//注册
int denglu(MSG xie,int sock);//登录
int danci(MSG xie,int sock);//查询
int lishi(MSG xie,int sock);//退出

int main(int argc, char const *argv[])
{
    if (argc<3)
    {
        printf("usage:<ip> <port>");
        return -1;
    }
    //创建套接字 用于链接
    int sock=socket(AF_INET,SOCK_STREAM,0);
    if (sock<0)
    {
        perror("socket err");
        return -1;
    }
    printf("sock:%d\n",sock);

    //连接服务器
    struct sockaddr_in add;
    socklen_t len=sizeof(add);   //填充的结构体的大小
    add.sin_family=AF_INET;  //协议族AF_INET
    add.sin_port=htons(atoi(argv[2]));    //端口
    add.sin_addr.s_addr=inet_addr(argv[1]); //ip地址转换为32位无符号长整数型数
    if (connect(sock,(struct sockaddr *)&add,len)< 0)
    {
        perror("connect err");
        return -1;
    }
    printf("connect success.\n");
    // printf("请输入选项:");
    MSG xie;//协议
    int A;
    
    while (1)
    {
        A=0;//选项
        caidan1();
        scanf("%d",&A);
        getchar();
        switch (A)
        {
            case 1:zhuce(xie,sock);break;//注册
            case 2: if (denglu(xie,sock)==1)goto next;else{break;}//登录
            case 3:close(sock);exit(0);break;//退出
            default:printf("输入错误啦\n");break;
        }
    }
next:
    while (1)
    {
        A=0;//选项
        caidan2();
        scanf("%d",&A);
        getchar();
        switch (A)
        {
            case 1:danci(xie,sock);break;//查询
            case 2:lishi(xie,sock);break;//历史记录
            case 3:close(sock);exit(0);break;//退出
            default:printf("输入错误啦\n");break;
        }
    }
    
    close(sock);
    return 0;
}

//登录菜单
void caidan1()                            
{
    printf("************************************\n");
    printf(" *                                *\n");
    printf(" *      《大威天龙云词典》        *\n");
    printf(" *                                *\n");
    printf(" *    1:注册 2:登录 3:退出     *\n");
    printf(" *                                *\n");
    printf("************************************\n");
    printf("请输入选项:");
}
//查询菜单
void caidan2()
{
    printf("*************************************\n");
    printf(" *                                 *\n");
    printf(" *       《大威天龙云词典》        *\n");
    printf(" *                                 *\n");
    printf(" *   1:查询 2:历史记录 3:退出   *\n");
    printf(" *                                 *\n");
    printf("*************************************\n");
    printf("请输入选项:");
}
//用户注册
int zhuce(MSG xie,int sock)
{
    xie.type=R;
    printf("请输入账号:");
    fgets(xie.name,sizeof(xie.name),stdin);
    if (xie.name[strlen(xie.name)-1]=='\n')
        xie.name[strlen(xie.name)-1]='\0';
    printf("请输入密码:");
    fgets(xie.data,sizeof(xie.data),stdin);
    if (xie.data[strlen(xie.data)-1]=='\n')
        xie.data[strlen(xie.data)-1]='\0'; 
    send(sock,&xie,sizeof(xie),0);
    recv(sock,&xie,sizeof(xie),0);
    printf("%s\n\n",xie.data);
    return 0;
}
//用户登录
int denglu(MSG xie,int sock)
{
    xie.type=L;
    printf("请输入账号:");
    fgets(xie.name,sizeof(xie.name),stdin);
    if (xie.name[strlen(xie.name)-1]=='\n')
        xie.name[strlen(xie.name)-1]='\0';
    strcpy(name,xie.name);//保存帐号,用于后期插入历史记录  
    printf("请输入密码:"); 
    fgets(xie.data,sizeof(xie.data),stdin);
    if (xie.data[strlen(xie.data)-1]=='\n')
        xie.data[strlen(xie.data)-1]='\0'; 
    send(sock,&xie,sizeof(xie),0);
    recv(sock,&xie,sizeof(xie),0);
    if (strncmp(xie.data,"OK",3)==0)
    {
        printf("登录成功\n\n");
        return 1;
    }
    else
    {   
        printf("账号或密码错误!\n\n");
        return 0;
    }
}
//查询单词
int danci(MSG xie,int sock)
{
    xie.type=Q;
    while (1)
    {
        strcpy(xie.name,name);//防止传输协议结构体中name数据丢失
        printf("\n要查询的单词(输入 # 退出):");
        fgets(xie.data,sizeof(xie.data),stdin);
        if (xie.data[strlen(xie.data)-1]=='\n')
            xie.data[strlen(xie.data)-1]='\0'; 
        if (strncmp(xie.data,"#",2)==0)
        {
            break;
        }
        send(sock,&xie,sizeof(xie),0);
        recv(sock,&xie,sizeof(xie),0);
        printf("\n释义:%s\n",xie.data);
        //if (strcmp(xie.data,"没有收录!")==0)
        //{
        //    break;
        //}
    }
    return 0;
}
//查询历史
int lishi(MSG xie,int sock)
{
    int rec;
    xie.type=H;
    strcpy(xie.name,name);//防止传输协议结构体中name数据丢失
    send(sock,&xie,sizeof(xie),0);
    putchar(10);
    while (recv(sock,&xie,sizeof(xie),0))
    {
        if (strncmp(xie.data,"OK",3)==0)//判断传输完历史记录
        {
            putchar(10);
            return 0;
        }
        if(strcmp(xie.data,"无历史记录!")==0)//判断有无历史记录
        {
            printf("%s\n",xie.data);
            return 0;
        }
        printf("%s\n",xie.data);
    }
    return 0;
}

Makefile 

all:
    gcc fuTCPfuTCP.c -lsqlite3 -o f  
    gcc keTCP.c -o k

clean:
    rm f k

txt索引导入数据库以及创建表代码

#include <stdio.h>
#include <sqlite3.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>

char *err=NULL;
int cidian(sqlite3 *db);//词典
int zhuce(sqlite3 *db);//创建注册表
int lishi(sqlite3 *db);//创建历史记录表
int main(int argc, char const *argv[])
{
    //打开或创建数据库
    sqlite3 *db=NULL;
    if (sqlite3_open("./cidian.db", &db)!=SQLITE_OK)
    {
        printf("sqlite3_open err:%s\n",sqlite3_errmsg(db));
        return -1;
    }
    printf("数据库打开成功。\n");
    cidian(db);
    zhuce(db);
    lishi(db);
    return 0;
}
//词典
int cidian(sqlite3 *db)
{
    //打开文件
    FILE *fop1=fopen("dict.txt","r");
    if (fop1<0)
    {
        perror("fopen1 err.");
        return -1;
    }
    //创建表
    if(sqlite3_exec(db,"create table cidian(单词 char,解释 char);",NULL,NULL,&err)!=SQLITE_OK)
    {
        printf("create err:%s\n",err);
    }
    printf("数据库创建成功。\n");
    //向表中插入数据
    char ci[1024]={0},jie[1024]={0},sql[1024]={0};
    char *p=NULL;
    int n,nn=1;  
    while (fgets(ci,sizeof(ci),fop1)!=NULL)//每次读取一行
    {
        n=0;
        p=strtok(ci," ");//遇到空格就分割单词,并获取单词
        //获取剩余单词
        while (p)//跳过单词,拼接释义
        {
            if (n==1)
            {
                strcat(jie,p);
                strncat(jie," ",1);
            }
            n=1;
            p=strtok(NULL," ");//获取单词
        }
        sprintf(sql,"insert into cidian values(\"%s\",\"%s\");",ci,jie);//拼接指令
        if(sqlite3_exec(db,sql,NULL,NULL,&err)!=SQLITE_OK)//写入数据库内容
        {
            printf("insert err:%s\n",err);
            return -1;
        }
        bzero(jie,sizeof(jie));
        printf("%d ",nn++);//计算行数
    }
    fclose(fop1);
    return 0;
}
//注册
int zhuce(sqlite3 *db)
{
    //创建表
    if(sqlite3_exec(db,"create table zhuce(帐号 char,密码 char);",NULL,NULL,&err)!=0)
    {
        printf("create err:%s\n",err);
    }
    printf("create success\n");
    //向表中插入数据
    if(sqlite3_exec(db,"insert into zhuce values(\"1\",\"1\");",NULL,NULL,&err)!=0)//提前插入内容防止查询出错
    {
        printf("insert err:%s\n",err);
        return -1;
    }
    printf("添加成功\n");
    return 0;
}
//历史
int lishi(sqlite3 *db)
{
    //创建表
    if(sqlite3_exec(db,"create table lishi(帐号 char,时间 char,单词 char);",NULL,NULL,&err)!=0)
    {
        printf("create err:%s\n",err);
    }
    printf("create success\n");
    //向表中插入数据
    if(sqlite3_exec(db,"insert into lishi values(\"1\",\"1\",\"1\");",NULL,NULL,&err)!=0)//提前插入内容防止查询出错
    {
        printf("insert err:%s\n",err);
        return -1;
    }
    printf("添加成功\n");
    return 0;
}
    

注意

导入代码运行时间较长!!!

数字是行数!!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Linux下实现电子词典代码可以采用如下的步骤: 1. 安装相关的开发工具和库:在Linux系统中,可以安装GCC编译器、make工具和ncurses库等开发工具和库,它们能够辅助实现电子词典的代码。 2. 创建一个数据库:使用mysql或sqlite等数据库软件,在Linux系统上创建一个用于存储词典数据的数据库。 3. 下载词典数据:从网上下载词典数据文件,可以选择免费的开源词典数据或商业的付费词典数据。 4. 解析词典数据:编写程序,读取并解析词典数据文件,将其存储到之前创建的数据库中。 5. 实现查询功能:编写查询程序,接收用户输入的查询词,将其与数据库中的词汇进行匹配,并显示查询结果。 6. 添加用户界面:借助ncurses库等,设计一个用户友好的界面,使用户能够方便地输入查询词,并查看查询结果。 7. 完善功能:在基本的查询功能基础上,可以增加一些额外的功能,如单词朗读、查看详细释义等,提高用户体验。 8. 测试和调试:对代码进行测试和调试,确保电子词典Linux系统上正常运行。 9. 部署和发布:将代码部署到Linux系统上,并按需求进行发布,使其他用户能够使用这个电子词典。 总结:通过上述步骤,我们可以在Linux系统上实现一个电子词典代码,用户可以通过输入查询词,使用查询功能来查找词汇的释义等信息。 ### 回答2: 在Linux下实现电子词典代码可以通过使用Python编程语言来实现。以下是一个使用Python编写的简单电子词典代码示例: ```python import json def load_data(): # 从文件中加载词典数据 with open('dictionary.json', 'r') as file: data = json.load(file) return data def search_word(word): # 在词典数据中搜索指定的单词并返回解释 data = load_data() if word in data: return data[word] else: return '该单词不存在' def main(): while True: print('请输入要查询的单词:') word = input() definition = search_word(word) print('解释:', definition) print('-------------------------') if __name__ == '__main__': main() ``` 以上代码中的`load_data`函数用于加载存储词典数据的`dictionary.json`文件。`search_word`函数用于在加载的词典数据中搜索指定的单词并返回解释。`main`函数是程序的入口,通过循环接收用户输入的单词并调用`search_word`函数进行查询,最后将查询结果打印出来。 为了使代码能够正常运行,需要准备一个存储词典数据的`dictionary.json`文件,该文件应具有以下格式: ```json { "apple": "苹果", "banana": "香蕉", "cat": "猫", ... } ``` 注意,以上只是一个简单的示例代码,实际的电子词典代码可能需要更复杂的功能,例如模糊搜索、数据的更新与维护等。这需要根据具体的需求来进行代码设计与功能实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值