基于QT实现的词典(附源码)

词典的功能主要分为五个部分,查询单词,查询历史记录,注册,登陆,删除历史记录。

主要用到的技术:JSON字符串,堆栈窗体(方便以后加新功能),QTcpSocket,LcdNumber,时间戳的转换。

通信用的是TCP通信,将TCP封在了一个头文件中,哪个文件想去通过TCP链接发送消息就可以使用头文件

QT端写的是客户端,服务器还是在我笔记上次的Linux系统下写的服务器,做了一些小修改

项目演示效果:

服务器代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/select.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "dictionary.h"
#include <sqlite3.h>
#include <signal.h>
#include <sys/wait.h>
#include <time.h>
#include "cJSON.h"

int acceptfd;
int search_word(int acceptfd);
int num = 10;
time_t t;
struct tm *tm;
char data[1024];
// 注册函数
void register_sev(int acceptfd, char *p, sqlite3 *db)
{
    char sql[128] = " "; //定义数组来装insert语句
    sprintf(sql, "insert into user values('%s','%s');", dic.name, dic.password);
    //如果插入不成功则给dic.text赋值失败反之OK
    if (sqlite3_exec(db, sql, NULL, NULL, &p) != SQLITE_OK)
    {
        strcpy(dic.text, "already exits!");
    }
    else
    {
        strcpy(dic.text, "OK");
    }
    dic.history_id = 1;
    cJSON *data = cJSON_CreateObject();
    cJSON_AddStringToObject(data, "text", dic.text);
    cJSON_AddNumberToObject(data, "history", dic.history_id);
    char *buf;
    buf = cJSON_PrintUnformatted(data);
    send(acceptfd, buf, strlen(buf), 0); //发送
}

// 登录函数
void login_sev(int acceptfd, char *p, char **result, int row, int line, sqlite3 *db)
{
    // 定义一个输入去接收这个查询用户名和密码的语句
    char buf[128];
    dic.history_id = 1;
    sprintf(buf, "select * from user where name = '%s' and password = '%s';", dic.name, dic.password);
    // 先把输入的数据查询一下在表里,如果表里有数据则代表数据库有密码
    if (sqlite3_get_table(db, buf, &result, &row, &line, &p) != SQLITE_OK)
    {
        perror("sev sqlite3_table error\n");
        return;
    }
    // 如果行大于零则代表有数据成功
    if (row > 0)
    {
        strcpy(dic.text, "login successs");
    }
    else
    {
        strcpy(dic.text, "login loose,please check your name or password!");
    }
    cJSON *data = cJSON_CreateObject();
    cJSON_AddStringToObject(data, "text", dic.text);
    cJSON_AddNumberToObject(data, "history", dic.history_id);
    char *str;
    str = cJSON_PrintUnformatted(data);
    send(acceptfd, str, strlen(str), 0); //发送
    return;
}

// 查询单词
int query_sev(int acceptfd, sqlite3 *db, char *p)
{

    time_t t;
    struct tm *tm;
    int a = 0;
    //定义一个语句去接受查询的语句
    char sql2[128] = "";
    if (!strcmp(dic.password, "#")) //如果在查找单词中输入#就会退出
    {
        return -1;
    }
    int found = search_word(acceptfd); //去接受查询单词这个函数的返回值 不为1则代表失败 返回1则代表成功
    if (found != 1)
    {   
        dic.history_id = 1;
        strcpy(dic.text, "can't find \n");
        cJSON *data = cJSON_CreateObject();
        cJSON_AddStringToObject(data, "text", dic.text);
        cJSON_AddNumberToObject(data, "history", dic.history_id);
        char *buf;
        buf = cJSON_PrintUnformatted(data);
        send(acceptfd, buf, strlen(buf), 0); //发送
    }
    else
    {

        time(&t);
        tm = localtime(&t);
        sprintf(dic.time_sev, "%d-%d-%d %d:%d:%d", tm->tm_year + 1900,
                tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
        sprintf(sql2, "insert into record values('%s','%s');", dic.password, dic.time_sev); // 成功后就把查询成功的单词插入到record这个表里
        if (sqlite3_exec(db, sql2, NULL, NULL, &p) != SQLITE_OK)
        {
            perror("record insert error\n");
            return -1;
        }
    }
    return 0;
}

// 查询单词函数
int search_word(int acceptfd)
{
    //定义每次接受来的密码的长度
    int len = strlen(dic.password);

    //打开文件用标准IO
    FILE *sp = fopen("dic.txt", "r");
    if (NULL == sp)
    {
        perror("sp error\n");
        return -1;
    }
    //如果dic.txt文件不为空时继续执行
    while (fgets(dic.text, sizeof(dic.text), sp) != NULL)
    {
        char buf[32] = {};
        for (int i = 0; i < 32; i++)
        {
            if (dic.text[i] != ' ')
            {
                buf[i] = dic.text[i];
            }
            else
            {
                break;
            }
        }
        //拿密码去比较文件中单词 如果成功发送dic 并且返回1
        if (!strcmp(buf, dic.password))
        {
            printf("%s\n", dic.text);
            cJSON *data = cJSON_CreateObject();
            cJSON_AddStringToObject(data, "text", dic.text);
            cJSON_AddNumberToObject(data, "history", dic.history_id);
            char *buf;
            buf = cJSON_PrintUnformatted(data);
            send(acceptfd, buf, strlen(buf), 0); //发送
            return 1;
        }
        else
        {
            continue;
        }
    }
    return -1;
}


//历史函数
int history_sev(char *p, sqlite3 *db)
{

    char buf[64] = "select * from record ;";
    char **pResult;
    int nRow;
    int nCol;
    strcpy(dic.text,"");

    if (sqlite3_get_table(db, buf, &pResult, &nRow, &nCol, &p) != SQLITE_OK)
    {
        fprintf(stderr, "select is error: %s\n", p); //如果不等于OK责代表没成功,报错
        return -1;
    }
    else
    {
        for (size_t i = 2; i < nRow * nCol + 2; i++)
        {
            strcat(dic.text, pResult[i]);
            strcat(dic.text, "\r\n");
        }
        printf("%s\n",dic.text);
        dic.history_id = 2;
        cJSON *data = cJSON_CreateObject();
        cJSON_AddStringToObject(data, "text", dic.text);
        cJSON_AddNumberToObject(data, "history", dic.history_id);
        char *buf;
        buf = cJSON_PrintUnformatted(data);
        send(acceptfd, buf, strlen(buf), 0); //发送
    }
    return 0;
}

//删除历史记录函数
void delete_history(char *p, sqlite3 *db)
{
    if (sqlite3_exec(db, "delete from record;", NULL, NULL, &p) != SQLITE_OK)
    {
        fprintf(stderr, "delete is error: %s\n", p); //如果不等于OK责代表没成功,报错
    }
    else
    {
        strcpy(dic.text, "删除成功!");
        cJSON *data = cJSON_CreateObject();
        cJSON_AddStringToObject(data, "text", dic.text);
        cJSON_AddNumberToObject(data, "history", dic.history_id);
        char *buf;
        buf = cJSON_PrintUnformatted(data);
        send(acceptfd, buf, strlen(buf), 0); //发送
    }
    return;
}

//处理僵尸进程
void hanlder(int arg)
{
    waitpid(-1, NULL, WNOHANG);
}

int main(int argc, char const *argv[])
{
    //1. 创建sql表
    sqlite3 *db = NULL;
    if (sqlite3_open("./dictionary.db", &db) != 0)
    {
        fprintf(stderr, "sqlite3 is error%s\n", sqlite3_errmsg(db));
        return -1;
    }
    // 创建两个表
    char *p = NULL;
    if (sqlite3_exec(db, "create table user(name char primary key, password char);", NULL, NULL, &p) != SQLITE_OK)
    {
        fprintf(stderr, "create stu1 is error %s\n", p);
        return -1;
    }

    if (sqlite3_exec(db, "create table record(password char,time char);", NULL, NULL, &p) != SQLITE_OK)
    {
        fprintf(stderr, "create record is error %s\n", p);
        return -1;
    }

    // 创建指针以及行和列的变量
    char **result = NULL;
    int row = 0;
    int line = 0;

    // 创建套接字
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        perror("sev sockfd error\n");
        return -1;
    }

    //填充结构体
    struct sockaddr_in saddr, caddr;
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(atoi(argv[1]));
    saddr.sin_addr.s_addr = inet_addr("192.168.50.248");
    int len = sizeof(caddr);

    // 绑定 和 监听
    if (bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
    {
        perror("bind error\n");
        return -1;
    }

    if (listen(sockfd, 5) < 0)
    {
        perror("sev listen error\n");
        return -1;
    }

    // 处理僵尸进程
    signal(SIGCHLD, hanlder);

    // 循环去接受
    while (1)
    {
        acceptfd = accept(sockfd, (struct sockaddr *)&caddr, &len);
        if (acceptfd < 0)
        {
            perror("sev acceptfd is error\n");
            return -1;
        }
        // 创建进程
        pid_t pid = fork();
        if (pid < 0)
        {
            perror("sev pid error\n");
            return -1;
        }
        else if (pid == 0) // 子进程
        {

            while (recv(acceptfd, data, sizeof(data), 0))
            {
                sleep(1);
                printf("%s\n", data);
                cJSON *root = cJSON_Parse(data);
                dic.type = cJSON_GetObjectItem(root, "type")->valueint;
                strcpy(dic.password, cJSON_GetObjectItem(root, "password")->valuestring);
                strcpy(dic.name, cJSON_GetObjectItem(root, "name")->valuestring);
                strcpy(dic.text, cJSON_GetObjectItem(root, "text")->valuestring);
                strcpy(dic.time_sev, cJSON_GetObjectItem(root, "time_sev")->valuestring);
                dic.history_id = 0;
                printf("type = %c\n", dic.type);
                printf("password = %s\n", dic.password);
                printf("name = %s\n", dic.name);
                printf("text = %s\n", dic.text);
                printf("time_sev = %s\n", dic.time_sev);
                printf("history_id = %d\n", dic.history_id);
                switch (dic.type)
                {
                case 'r':
                    register_sev(acceptfd, p, db); // 注册函数
                    break;
                case 'l':
                    login_sev(acceptfd, p, result, row, line, db); // 登录函数
                    break;
                case 'q':
                    query_sev(acceptfd, db, p); //查询函数
                    break;
                case 'h':
                    history_sev(p, db); //历史查询函数
                    break;
                case 'd':
                    delete_history(p, db); // 历史记录删除函数
                    break;
                default:
                    break;
                }
            }
        }
        else // 父进程
        {
            close(acceptfd);
        }
    }

    return 0;
}

感谢大家的观看~,QT源码在最上方哦

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笨笨小乌龟11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值