单词助手(可联网)

基本功能

1. 可实现对本地词库添加、删除单词功能
2. 可实现查词功能,根据英文查释义,优先从本地词库查询,如果本地词库没有就自动网上查询,并将其添加至本地词库
3. 可实现学习功能,每天50词,可分批次学习,并有根据单词选择释义和根据释义写单词两种学习方式
4. 可实现错误回顾功能,在学习过程中出错的词都保存在文件中,用于下次回顾
5. 可实现服务器多并发

涉及技术

1. C/C++
2. 文件操作
3. socket网络编程
4. linux系统编程

需要工具

1. openssl
2. curl
3. 百度翻译api

注:openssl和curl安装在服务器(阿里云或腾讯云服务器)中,百度翻译api可在百度翻译平台免费申请标准版,好像有词量限制,但也够用了。具体安装步骤网上教程很多,此处不做赘述。服务器详情请参考https://blog.csdn.net/weixin_44690490/article/details/104342427

代码逻辑

  1. 添加:定义一个结构体,包含单词和释义两个字符数组,并对其赋值,再将这个结构体写进词库文件尾部
  2. 删除:先将词库文件a更名为b,在读取整个词库文件b,查找出需要删除的单词word,再创建一个与词库文件之前名称a相同的文件c,此时c就成为了词库文件,再将word前后的数据写进文件c中,最后删除文件b
  3. 学习:先读取文件数据,在随机抽取其中一个词,按照需要的学习方式输入答案,答错就将这个单词保存在vector容器中,无论答错答对今日任务量都减一,在退出程序前将当前完成量以及时间记录在文件中,在下次启动程序时判断日期是否发生变化,是则将文件中的数据清零,否则保持不变。(具体整个学习方式的逻辑很简单,没有解释点)
  4. 回顾:在学习中出错的单词都记录在vector容器中,在学习完后可继续进行错误回顾,回答正确就将该单词进行尾删,仍然错误继续存入容器中。如果学习完成后退出了程序,此时就将vector容器中的数据写入文件中,便于下一次回顾。
  5. 查找:先读取词库,如果在词库内找不到你想要的单词,此时判断电脑是否联网,已联网就连接并将单词发送给服务器,服务器通过百度翻译api向百度翻译发起请求,百度翻译相应后就将释义返回给服务器,服务器再将其返回给客户端
  6. 服务器多并发:创建一个线程p,主线程用于connect连接,p线程用于与客户端的数据通信

代码

头文件 English.hpp

#pragma once
#ifndef ENGLISH_H
#define ENGLISH_H#define _WINSOCKAPI_  
#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS#include <iostream>
#include <vector>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <Winsock2.h> 
#include <Wininet.h>
#include <string>
#include <stdio.h>
#include <time.h>
#include <conio.h>
#pragma comment(lib,"Ws2_32.lib")
#pragma comment(lib,"Wininet.lib")using namespace std;#define len 2
#define std_size 50
#define everyday_word 50
#define EXIT 0
#define RIGHT 1
#define ERRO -1typedef struct WordNew
{char word[std_size];//单词char mean[std_size];//释义
}WordNew;typedef struct AllAnswer
{char A_answer[std_size];//答案Achar B_answer[std_size];//答案Bchar C_answer[std_size];//答案Cchar D_answer[std_size];//答案D
}AllAnswer;typedef struct Data
{int			study_num;//已学习数目int         error;//错误题数SYSTEMTIME	time;//系统时间
}Data;typedef struct FileName
{char word_file[10] = "word.txt";char cur_file[10] = "cur.txt";char error_num_file[15] = "error_num.txt";char error_word_file[15] = "error_word.txt";char data_file[10] = "data.txt";
}filename;typedef struct InterNew
{SOCKADDR_IN addr;SOCKET sockid;int port;char ip[20];bool cur_connect;//当前连接标记
}InterNew;class Internet
{
public:Internet(){internew.cur_connect = false;}~Internet(){}void  Tips(char *test){char title[100] = { "温馨提示" };MessageBox(NULL, TEXT(test), TEXT(title), MB_OK | MB_SYSTEMMODAL);}void _WSAStartup(){WSADATA wsd;if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0){Tips("   WSAStartup失败");exit(0);}}SOCKET CreateSocket(){SOCKET sockid = socket(AF_INET, SOCK_STREAM, 0);if (sockid < 0){Tips("      创建socket失败");exit(0);}return sockid;}void SetAddr(int port, char ip[],SOCKET sockid){internew.addr.sin_family = AF_INET;internew.addr.sin_port = htons(port);internew.addr.sin_addr.S_un.S_addr = inet_addr(ip);internew.port = port;strcpy(internew.ip, ip);internew.sockid = sockid;}void Connect(InterNew &internew){if (connect(internew.sockid, (SOCKADDR *)&(internew.addr), sizeof(internew.addr)) != 0){internew.cur_connect = false;}else{internew.cur_connect = true;}}void JudgeInter(InterNew &internew){DWORD   flag;if (InternetGetConnectedState(&flag, 0)){internew.cur_connect = true;}else{internew.cur_connect = false;}}int Send(char *data, int size){int ret = send(internew.sockid, data, size, 0);return ret;}int Recv(InterNew &internew, char *data, int size){int ret = recv(internew.sockid, data, size, 0);return ret;}void GetData(char *data,char *chiness){char *ptr = strstr(data, "\"dst\":");ptr += 7;int size = strlen(ptr);char *tmp = new char[size];memset(tmp, 0, size);for (int i = 0;ptr[i] != '\"';i++){tmp[i] = ptr[i];}string tem = MyUnEscape(tmp);strcpy(chiness, tem.c_str());delete[] tmp;}InterNew internew;//网络连接需要的信息
private:string Utf8Code2String(char* szCode){string strRet = "";for (int i = 0; i < 4; i++){if (szCode[i] >= '0' && szCode[i] <= '9')	continue;if (szCode[i] >= 'A' && szCode[i] <= 'F')	continue;if (szCode[i] >= 'a' && szCode[i] <= 'f')	continue;return strRet;}char unicode_hex[5] = { 0 };memcpy(unicode_hex, szCode, 4);unsigned int iCode = 0;sscanf_s(unicode_hex, "%04x", &iCode);wchar_t wchChar[4] = { 0 };wchChar[0] = iCode;char szAnsi[8] = { 0 };WideCharToMultiByte(CP_ACP, NULL, wchChar, 1, szAnsi, sizeof(szAnsi), NULL, NULL);strRet = string(szAnsi);return strRet;}string MyUnEscape(char* szUtf8Code){string strRet = "";char* szDelimiters = "\\u";char* pTok = strtok(szUtf8Code, szDelimiters);while (pTok != NULL) {if (strlen(pTok) >= 4){strRet += Utf8Code2String(pTok);}pTok = strtok(NULL, szDelimiters);}return strRet;}
};class  Word
{
public:Word(){}~Word(){}void InputWord(){memset(&_word, 0, sizeof(_word));cout << "请输入单词:";cin >> _word.word;cout << endl;cout << "请输入释义:";cin >> _word.mean;cout << endl;}void AddWord()//添加单词{FILE *fp = fopen(file.word_file, "ab");if (fp == NULL){cout << "在添加中word.txt打开失败" << endl;exit(0);}fwrite(&_word,sizeof(WordNew),1,fp);//向文件添加数据_word_num++;//单词数量加一fclose(fp);}int Search(char *fileName,char *word)//查找指定单词位置{int i = 0;WordNew *tmp = new WordNew[len];FILE *fp = fopen(fileName, "rb");while (!feof(fp)){memset(tmp, 0, sizeof(WordNew)*len);fread(tmp, sizeof(WordNew), len,fp);//每次从文件中读取len个数据for (int j = 0;j < len;j++){if (!strcmp(tmp[j].word, word))//判断是否与指定删除的数据相等{fclose(fp);delete[] tmp;return i;}i++;}}fclose(fp);delete[] tmp;return -1;//没有返回-1}char *SearchWord(char *word, Internet &inter, int size)//查找单词{inter.JudgeInter(inter.internew);FILE *fp = fopen(file.word_file, "rb");int num = Search(file.word_file, word);if (num != -1){fseek(fp, num * sizeof(WordNew), SEEK_SET);memset(&_word, 0, sizeof(_word));fread(&_word, sizeof(_word), 1, fp);fclose(fp);return _word.mean;}else{if (inter.internew.cur_connect){char *data = new char[100];memset(data, 0, 100);if ((inter.Send(word, size)) == SOCKET_ERROR){Tips("服务器已关闭");delete[] data;exit(0);}Sleep(100);inter.Recv(inter.internew, data, 100);char ptr[10] = { 0 };inter.GetData(data, ptr);//将本地没有的新单词键入文件memset(&_word, 0, sizeof(_word));strcpy(_word.word, word);strcpy(_word.mean, ptr);AddWord();fclose(fp);delete[] data;return _word.mean;}return NULL;}}void Delete(char *fileNmae1,char *fileName2,char *word)//删除指定单词{//fileNmae1  word.txtint pos = Search(fileNmae1, word);if (pos != -1)//找到指定数据了{char scr_name[MAX_PATH] = { 0 };//windows操作系统上,文件名字最大260个字符char dst_name[MAX_PATH] = { 0 };GetCurrentDirectory(MAX_PATH, scr_name);GetCurrentDirectory(MAX_PATH, dst_name);sprintf(scr_name, "%s\\%s", scr_name, fileNmae1);sprintf(dst_name, "%s\\%s", dst_name, fileName2);rename(scr_name, dst_name);//将word.txt改为cur.txtWordNew *tmp = new WordNew[_word_num];WordNew *tem = tmp;memset(tmp, 0, sizeof(WordNew)*_word_num);FILE *fcur = fopen(fileName2, "rb");FILE *fp = fopen(fileNmae1, "wb");fread(tem, sizeof(WordNew), _word_num, fcur);fwrite(tem,sizeof(WordNew),pos,fp);//把pos前的写进word.txttem += (pos + 1);fwrite(tem, sizeof(WordNew), _word_num - pos - 1, fp);//把pos后的写进word.txtfclose(fcur);fclose(fp);remove(dst_name);//删除cur.txtdelete[] tmp;tem=nullptr;cout << "删除成功" << endl;cout << endl;}else{cout << "没有该单词,无法删除" << endl;cout << endl;}}int WordToMean(WordNew *tmp,int num)//根据单词写释义{int return_val = 0;//EXIT 强制退出  RIGHT  答对  ERROR  答错char choose = 0;cout << tmp[num].word << endl; int k = (rand() % 4 + rand() % 4 + rand() % 4) / 3;memset(_answer.A_answer, 0, std_size);memset(_answer.B_answer, 0, std_size);memset(_answer.C_answer, 0, std_size);memset(_answer.D_answer, 0, std_size);switch (k){case 0: {sprintf(_answer.A_answer, "a、%s", tmp[num].mean);sprintf(_answer.B_answer, "b、%s", tmp[(rand() % _word_num + rand() % _word_num+ rand() % _word_num) / 3].mean);sprintf(_answer.C_answer, "c、%s", tmp[(rand() % _word_num + rand() % _word_num+ rand() % _word_num) / 3].mean);sprintf(_answer.D_answer, "d、%s", tmp[(rand() % _word_num + rand() % _word_num+ rand() % _word_num) / 3].mean);}break;case 1: {sprintf(_answer.A_answer, "a、%s", tmp[(rand() % _word_num + rand() % _word_num + rand() % _word_num) / 3].mean);sprintf(_answer.B_answer, "b、%s", tmp[num].mean);sprintf(_answer.C_answer, "c、%s", tmp[(rand() % _word_num + rand() % _word_num+ rand() % _word_num) / 3].mean);sprintf(_answer.D_answer, "d、%s", tmp[(rand() % _word_num + rand() % _word_num+ rand() % _word_num) / 3].mean);}break;case 2: {sprintf(_answer.A_answer, "a、%s", tmp[(rand() % _word_num + rand() % _word_num+ rand() % _word_num) / 3].mean);sprintf(_answer.B_answer, "b、%s", tmp[(rand() % _word_num + rand() % _word_num+ rand() % _word_num) / 3].mean);sprintf(_answer.C_answer, "c、%s", tmp[num].mean);sprintf(_answer.D_answer, "d、%s", tmp[(rand() % _word_num + rand() % _word_num + rand() % _word_num) / 3].mean);}break;case 3: {sprintf(_answer.A_answer, "a、%s", tmp[(rand() % _word_num + rand() % _word_num+ rand() % _word_num) / 3].mean);sprintf(_answer.B_answer, "b、%s", tmp[(rand() % _word_num + rand() % _word_num+ rand() % _word_num) / 3].mean);sprintf(_answer.C_answer, "c、%s", tmp[(rand() % _word_num + rand() % _word_num+ rand() % _word_num) / 3].mean);sprintf(_answer.D_answer, "d、%s", tmp[num].mean);}break;}cout << _answer.A_answer << endl;cout << _answer.B_answer << endl;cout << _answer.C_answer << endl;cout << _answer.D_answer << endl;cout << "它的意思为:";cin >> choose;cout << endl;if (choose == '0')//按0退出{cout << "已退出" << endl;return_val = EXIT;return return_val;}if (choose-k==97){return_val = RIGHT;cout << "恭喜你回答正确!" << endl;}else{cout << "回答错误" << endl;cout << tmp[num].word << "———" << tmp[num].mean << endl;cout << endl;return_val = ERRO;Sleep(1000);}return return_val;}int MeanToWord(WordNew *tmp, int num){int return_val = 0;//EXIT 强制退出  RIGHT  答对  ERROR  答错char word[std_size] = { 0 };cout << tmp[num].mean << endl;cout << "请写出单词:";cin >> word;if (word[0] == '0')//按0退出{cout << "已退出" << endl;return_val = EXIT;return return_val;}if (!strcmp(tmp[num].word, word)){cout << "恭喜你回答正确!" << endl;return_val = RIGHT;cout << endl;}else{cout << "回答错误" << endl;cout << tmp[num].mean << "———" << tmp[num].word << endl;cout << endl;return_val = ERRO;Sleep(1000);}return return_val;}void  CanChoose()//功能选择{cout << "****************************************" << endl;cout << "********* 根据序号选择功能 *************" << endl;cout << "********* 1、添加  2、删除 *************" << endl;cout << "********* 3、查找  4、学习 *************" << endl;cout << "********* 5、回顾  0、退出 *************" << endl;cout << "****************************************" << endl;}void StudyWayChoose()//学习方式选择{cout << "****************************************" << endl;cout << "********* 根据序号选择功能 *************" << endl;cout << "****** 1、根据英语选择汉语释义  ********" << endl;cout << "****** 2、根据汉语写单词        ********" << endl;cout << "****** 0、返回主菜单             *******" << endl;cout << "****************************************" << endl;}void ErrorReview()//错误回顾{int val = 0;int num = 0;int error = 0;//错误回顾中回答错误的数FILE *ferror_num = fopen(file.error_num_file, "rb");if (ferror_num == NULL){Tips("在回顾中以读形式打开error_num_file.txt文件失败");exit(0);}FILE *ferror_word = fopen(file.error_word_file, "rb");if (ferror_word == NULL){Tips("在回顾中以读形式打开error_word_file.txt文件失败");fclose(ferror_num);exit(0);}fseek(ferror_num, 0, SEEK_END);int error_num_size = ftell(ferror_num) / sizeof(int);fseek(ferror_num, 0, SEEK_SET);fseek(ferror_word, 0, SEEK_END);int error_word_size = ftell(ferror_word) / sizeof(int);fseek(ferror_word, 0, SEEK_SET);if (error_word.size() || error_num.size() || error_num_size || error_word_size){WordNew *tmp = new WordNew[_word_num];memset(tmp, 0, sizeof(WordNew)*_word_num);FILE *fp = fopen(file.word_file, "rb");if (fp == NULL){Tips("在回顾中以读的形式打开word.txt失败" );delete[] tmp;exit(0);}fread(tmp, sizeof(WordNew), _word_num, fp);fclose(fp);if (error_word.size() || error_num.size()){cout << "你需要回顾 " << error_word.size() + error_num.size() << "个单词" << endl;cout << "开始错误回顾" << endl;int error_num_size = error_num.size() - 1;int error_word_size = error_word.size() - 1;while (error_num.size()){cout << "											错误  " << error << "个" << endl;num = (error_num)[error_num_size];val = WordToMean(tmp, num);if (val == EXIT)//强制退出{delete[] tmp;return;}else if (val == RIGHT)//回答正确{error_num_size--;data.error--;error_num.pop_back();}else//回答错误{error++;error_num.pop_back();}}while (error_word.size()){cout << "											错误  " << error << "个" << endl;num = (error_word)[error_word_size];val = MeanToWord(tmp, num);if (val == EXIT){delete[] tmp;return;}else if (val == RIGHT){error_word_size--;data.error--;error_word.pop_back();}else{error;error_word.pop_back();}}}if(error_num_size || error_word_size){cout << "你需要回顾 " << error_word_size + error_num_size << "个单词" << endl;cout << "开始错误回顾" << endl;int i = 0;num = 0;while (!feof(ferror_num) && error_num_size){cout << "											错误  " << error << "个" << endl;fread(&num, sizeof(int), 1, ferror_num);val = WordToMean(tmp, num);if (val == EXIT){fclose(ferror_num);fclose(ferror_word);delete[] tmp;return;}else if (val == ERRO){error++;fclose(ferror_num);ferror_num = fopen(file.error_num_file, "ab");if (ferror_num == NULL){Tips("在回顾中以写形式打开error_num_file.txt文件失败" );delete[] tmp;exit(0);}fwrite(&num, sizeof(int), 1, ferror_num);fclose(ferror_num);ferror_num = fopen(file.error_num_file, "rb");fseek(ferror_num, i*sizeof(int), SEEK_SET);if (ferror_num == NULL){Tips("在回顾中再次以读形式打开ferror_num.txt文件失败");delete[] tmp;exit(0);}}else{data.error --;}i++;}fclose(ferror_num);i = 0;while (!feof(ferror_word) && error_word_size){cout << "											错误  " << error << "个" << endl;fread(&num, sizeof(int), 1, ferror_word);val = MeanToWord(tmp, num);if (val == EXIT){fclose(ferror_num);fclose(ferror_word);delete[] tmp;return;}else if (val == ERRO){error++;fclose(ferror_word);ferror_word = fopen(file.error_word_file, "ab");if (ferror_word == NULL){Tips("在回顾中以写形式打开error_word_file.txt文件失败");delete[] tmp;exit(0);}fwrite(&num, sizeof(int), 1, ferror_word);fclose(ferror_word);ferror_word = fopen(file.error_word_file, "rb");fseek(ferror_word, i*sizeof(int), SEEK_SET);if (ferror_word == NULL){Tips("在回顾中再次以读形式打开error_word_file.txt文件失败");delete[] tmp;exit(0);}}else{data.error--;}}i++;}fclose(ferror_word);ClearFile(file.error_num_file);ClearFile(file.error_word_file);//清零文件中错误数Data *ptr = new Data;memset(ptr, 0, sizeof(Data));FILE *fcur = fopen(file.data_file, "rb");if (fcur == NULL){Tips("在回顾中以读的形式打开data.txt文件失败" );delete[] tmp;delete ptr;exit(0);}fread(tmp, sizeof(Data), 1, fcur);ptr->error = 0;fclose(fcur);fcur = fopen(file.data_file, "wb");if (fcur == NULL){Tips("在回顾中以写的形式打开data.txt文件失败");delete[] tmp;delete ptr;exit(0);}fwrite(ptr, sizeof(Data), 1, fcur);fclose(fcur);cout << "错误回顾结束" << endl;delete[] tmp;}else{cout << "暂无错误"<<endl;}}void ClearFile(char *fileName){FILE *fp = fopen(fileName, "w");fclose(fp);}void  Tips(char *test){char title[100] = { "温馨提示" };		MessageBox(NULL, TEXT(test), TEXT(title), MB_OK | MB_SYSTEMMODAL);}void JudgeTodayFinish(int error_num,int study_num){char test[100] = { 0 };int  error = error_num;//错误单词数int  cur_no_finish = everyday_word - study_num;//未完成数if (error > 0 && cur_no_finish > 0){sprintf(test, "今日还有%d个单词没有完成\n    还有%d个单词没有回顾", cur_no_finish, error);Tips(test);}else if (error > 0 && cur_no_finish == 0){sprintf(test, "  今日还有%d个单词没有回顾", error);Tips(test);}else if (error == 0 && cur_no_finish > 0){sprintf(test, "  今日还有%d个单词没有完成\n", cur_no_finish);Tips(test);}else{sprintf(test, "    今日任务已完成\n");Tips(test);}}void JudgeYesterdayFinish(int error_num, int study_num){char test[100] = { 0 };int  error = error_num;//错误单词数int  cur_no_finish = everyday_word - study_num;//未完成数if (error > 0 && cur_no_finish > 0){sprintf(test, "昨日还有%d个单词没有完成\n    还有%d个单词没有回顾", cur_no_finish, error);Tips(test);}else if (error > 0 && cur_no_finish == 0){sprintf(test, "  昨日还有%d个单词没有回顾", error);Tips(test);}else if (error == 0 && cur_no_finish > 0){sprintf(test, "  昨日还有%d个单词没有完成\n", cur_no_finish);Tips(test);}else{sprintf(test, "    昨日任务已完成\n");Tips(test);}}void Init(){bool flag = true;//标记是否有data.txt,true表示有memset(&data, 0, sizeof(data));//初始化学习进度//判断是否有word.txt、data.txt等文件,无则生成一个FILE *fcur = fopen(file.data_file, "rb");if (fcur == NULL){fcur = fopen(file.data_file, "wb");fclose(fcur);flag = false;fcur = fopen(file.data_file, "rb");}FILE *fp = fopen(file.word_file, "r");if (fp == NULL){fp = fopen(file.word_file, "w");}FILE *ferror_num = fopen(file.error_num_file, "r");if (ferror_num == NULL){ferror_num = fopen(file.error_num_file, "w");fclose(ferror_num);}FILE *ferror_word = fopen(file.error_word_file, "r");if (ferror_word == NULL){ferror_word = fopen(file.error_word_file, "w");fclose(ferror_word);}fseek(fp, 0, SEEK_END);_word_num = ftell(fp) / sizeof(WordNew);//获取单词数GetLocalTime(&(data.time));//获取当前时间Data *ptr = new Data;memset(ptr, 0, sizeof(Data));fread(ptr, sizeof(Data), 1, fcur);fclose(fp);fclose(fcur);	if ((ptr->time.wDay != data.time.wDay) && flag){fcur = fopen(file.data_file, "wb");fwrite(&data, sizeof(Data), 1, fcur);JudgeTodayFinish(0,0);JudgeYesterdayFinish(ptr->error, ptr->study_num);}else{JudgeTodayFinish(ptr->error, ptr->study_num);}fclose(fcur);delete ptr;}void SaveErroe(){int size = error_num.size();int num = 0;if (size != 0){FILE *ferror_num = fopen(file.error_num_file, "wb");for (int i = 0;i < size;i++){num = error_num[i];fwrite(&num, sizeof(int), 1, ferror_num);}fclose(ferror_num);}size = error_word.size();if (size != 0){FILE *ferror_word = fopen(file.error_word_file, "wb");for (int i = 0;i < size;i++){num = error_word[i];fwrite(&num, sizeof(int), 1, ferror_word);}fclose(ferror_word);}Data *ptr = new Data;memset(ptr, 0, sizeof(Data));FILE *fcur = fopen(file.data_file, "rb");if (fcur == NULL){Tips("在保存中以读形式打开data.txt失败");delete ptr;exit(0);}fread(ptr, sizeof(Data), 1, fcur);fclose(fcur);data.error = error_num.size() + size + ptr->error;//错误题数data.study_num = data.study_num + ptr->study_num;GetLocalTime(&(data.time));fcur = fopen(file.data_file, "wb");if (fcur == NULL){Tips("在保存中以写形式打开data.txt失败");delete ptr;exit(0);}fwrite(&data, sizeof(Data), 1, fcur);delete ptr;fclose(fcur);}int _word_num;//单词数量Data data;filename file;vector<int> error_num;vector<int> error_word;
private:WordNew _word;AllAnswer _answer;
};

具体执行文件 main.cpp

#include "English.hpp"
using namespace std;LPTHREAD_START_ROUTINE *Connect(LPVOID inter)
{Internet cur_inter = *((Internet *)inter);while (1){cur_inter.Connect(cur_inter.internew);}return 0;
}void Inter(Internet &inter)
{int port = 5188;//端口号char ip[20] = "*********";//服务器ipinter._WSAStartup();SOCKET sockid=inter.CreateSocket();inter.SetAddr(port,ip, sockid);
}void WordRandomised(Word &word_data)//单词速记
{LPDWORD tid = 0;int choose = 0;int flag = 1;int num = 0;//接收产生的随机数FILE *fp = fopen(word_data.file.word_file, "rb");if (fp == NULL){word_data.Tips("在加载中以读的形式打开word.txt失败");exit(0);}WordNew *tmp = new WordNew[word_data._word_num];memset(tmp, 0, sizeof(WordNew)*word_data._word_num);fread(tmp, sizeof(WordNew), word_data._word_num, fp);fclose(fp);word_data.StudyWayChoose();cout << "请输入序号:";do{if (num != 0){cout << "请输入范围以内的数" << endl;cout << endl;word_data.StudyWayChoose();cout << "请输入序号:";}cin >> choose;num++;} while (!(choose < 3 && choose > -1));num = 0;cout << endl;switch (choose){case 0:{break;}case 1:{while ((everyday_word != word_data.data.study_num)){cout << "                                           完成进度  " << word_data.data.study_num << "/" << everyday_word << endl;cout << "											错误  " << word_data.error_num.size() << "个" << endl;num = rand() % (word_data._word_num);int answer = word_data.WordToMean(tmp, num);if (answer == EXIT){break;}if (answer == ERRO){word_data.data.error++;word_data.error_num.push_back(num);}word_data.data.study_num++;}}break;case 2:{while ((everyday_word != word_data.data.study_num)){cout << "                                           完成进度  " << word_data.data.study_num << "/" << everyday_word << endl;cout << "											错误  " << word_data.error_word.size() << "个" << endl;num = rand() % word_data._word_num;int answer = word_data.MeanToWord(tmp, num);if (answer == EXIT){break;}if(answer == ERRO){word_data.data.error++;word_data.error_word.push_back(num);}word_data.data.study_num++;}}break;default:break;}delete[] tmp;}void  True(Word &word_data, Internet &inter)
{int num = 0;int choose = 0;int flag = 1;Inter(inter);LPDWORD tid = 0;CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&Connect, (LPVOID)&inter, 0, tid);while (flag){word_data.CanChoose();cout << "请输入序号:";do{if (num != 0){cout << "请输入范围内的序号" << endl;word_data.CanChoose();cout << "请输入序号:";}cin >> choose;num++;} while (!(choose > -1 && choose < 6));cout << endl;num = 0;switch (choose){case 0:{flag = 0;TerminateThread(tid,NULL);}break;case 1:{word_data.InputWord();word_data.AddWord();cout << "添加成功" << endl;}break;case 2:{char word[std_size] = { 0 };cout << "请输入单词:";cin >> word;word_data.Delete(word_data.file.word_file, word_data.file.cur_file, word);}break;case 3:{char word[std_size] = { 0 };cout << "请输入单词:";cin >> word;char *ptr=word_data.SearchWord(word,inter,strlen(word));if (ptr != NULL){cout << ptr << endl;}else{cout << "没有该数据" << endl;}}break;case 4:{WordRandomised(word_data);}break;case 5:{word_data.ErrorReview();}break;default:break;}}
}Data *ReadFile(Word &word_data)
{FILE *fcur = fopen(word_data.file.data_file, "rb");if (fcur == NULL){word_data.Tips("在主函数中打开data.txt文件失败");exit(0);}Data *ptr = new Data;memset(ptr, 0, sizeof(Data));fread(ptr, sizeof(Data), 1, fcur);fclose(fcur);return ptr;
}int main()
{srand((unsigned int)time(NULL));Word word_data;Internet inter;word_data.Init();True(word_data, inter);word_data.SaveErroe();Data *ptr = ReadFile(word_data);word_data.JudgeTodayFinish(ptr->error,ptr->study_num);return 0;
}

服务器程序

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <sys/select.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <curl/curl.h>
#include <openssl/md5.h>
#include <pthread.h>typedef struct client_new
{char *ip_addr;int sockid;
}client_new;void Getchinsee(char *word,char *data)
{CURL *curl;CURLcode res;curl = curl_easy_init();if(curl) {char myurl[1000] = "http://api.fanyi.baidu.com/api/trans/vip/translate?";char *appid = "********";   //百度翻译给的appid值char q[] = " ";     strcpy(q,word);char *from = "en";          char *to = "zh";            char salt[60];int a = rand();sprintf(salt,"%d",a);char *secret_key = "*******";   //百度翻译给的keychar sign[120] = "";strcat(sign,appid);strcat(sign,q);strcat(sign,salt);strcat(sign,secret_key);unsigned char md[16];int i;char tmp[3]={'\0'},buf[33]={'\0'};MD5((unsigned char *)sign,strlen((const char *)sign),md);for (i = 0; i < 16; i++){sprintf(tmp,"%2.2x",md[i]);strcat(buf,tmp);}strcat(myurl,"appid=");strcat(myurl,appid);strcat(myurl,"&q=");strcat(myurl,q);strcat(myurl,"&from=");strcat(myurl,from);strcat(myurl,"&to=");strcat(myurl,to);strcat(myurl,"&salt=");strcat(myurl,salt);strcat(myurl,"&sign=");strcat(myurl,buf);//设置访问的地址curl_easy_setopt(curl, CURLOPT_URL, myurl);FILE *fp= fopen("a.txt", "wb");curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);res = curl_easy_perform(curl);fclose(fp);/* Check for errors */ if(res != CURLE_OK)fprintf(stderr, "curl_easy_perform() failed: %s\n",curl_easy_strerror(res));curl_easy_cleanup(curl);fp= fopen("a.txt", "rb");fread(data,1,100,fp);fclose(fp);}
}void *do_work(void *_client)
{char recvive[1024]={0};client_new *client=(client_new *)_client;int flag=0;char data[100]={0};while(1){memset(recvive,0,1024);flag=recv(client->sockid,recvive,1024,0);if(flag>0){Getchinsee(recvive,data);send(client->sockid,data,strlen(data),0);memset(data,0,100);memset(recvive,0,1024);}else{memset(recvive,0,sizeof(recvive));printf("ip=%s  已断开!\n",client->ip_addr);getcwd(recvive, 100);sprintf(recvive,"%s/%s",recvive,"a.txt");remove(recvive);break;}}return 0;
}int internet()
{struct sockaddr_in sockaddr;sockaddr.sin_family=AF_INET;sockaddr.sin_port=htons(5188);sockaddr.sin_addr.s_addr=htonl(INADDR_ANY);int sockid=socket(AF_INET,SOCK_STREAM,0);const int on=1;if(setsockopt(sockid,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))<0){printf("setsockopt\n");return 0;}if(bind(sockid,(struct sockaddr *)&sockaddr,sizeof(sockaddr))<0){printf("bind\n");return 0;}if(listen(sockid,SOMAXCONN)<0){printf("listen\n");return 0;}struct sockaddr_in other_sock_addr;socklen_t other_sock_addr_len=sizeof(other_sock_addr);while(1){int sockid_client=accept(sockid,(struct sockaddr *)&other_sock_addr,&other_sock_addr_len);client_new client;memset(&client,0,sizeof(client));client.ip_addr=inet_ntoa(other_sock_addr.sin_addr);client.sockid=sockid_client;printf("ip=%s  已连接!\n",client.ip_addr);pthread_t tid=0;pthread_create(&tid,NULL,do_work,(void *)&client);}	return 0;
}int main()
{internet();return 0;
}

注:服务器编译指令
gcc -Wall -lcurl -lssl -lcrypto server.c -o server -lpthread

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/545693.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity查安卓Native Crash的方法,定位SO报错函数

需要用到两个工具Il2CppDumper和IDA_Pro&#xff0c;网上可以下到对应的软件 可以看到报错的位置是libil2cpp.so 0000000000AFF820 接下来要做的事情就是找到0000000000AFF820对应的函数是哪个 解包 Il2CppDumper解析so文件和符号表&#xff0c;查看对应的函数表 把apk后缀…

WebApi系列~自主宿主HttpSelfHost的实现

回到目录 宿主一词我们不会陌生&#xff0c;它可以看作是一个基础设施&#xff0c;它为一些服务和功能提供最底层的支持&#xff0c;如你的web应用程序可以运行在iis或者apache上&#xff0c;而这两个东西就是web应用程序的宿主&#xff0c;而今天说的自主宿主SelfHost就是说&a…

第 2-2 课:各种内部类和枚举类 + 面试题

内部类不仅经常出现在各种面试题中,还会在 Java 源码中频频出现,因此只有搞明白了 Java 内部类,才能搞定面试和看懂各种 Java 源码。 内部类 Java 内部类,分为以下四种: 成员内部类静态成员内部类局部内部类匿名内部类下面分别来看这些内部类的使用。 成员内部类 定义…

linux系统层次结构_Linux文件系统层次结构问题和解答

linux系统层次结构This section contains Aptitude Questions and Answers on Linux Filesystem Hierarchy. 本节包含有关Linux文件系统层次结构的 Aptitude问答。 1) There are the following statements that are given below, which of them are correct about Linux File …

plsql developer 安装在win7 64位电脑路径问题

plsql developer 如果安装在win7 64位电脑上&#xff0c;安装目录不能有括号或者中文等特殊字符&#xff0c;默认安装路径是C:\Program Files (x86)。——

第 2-4 课:克隆和序列化 + 面试题

克隆 在开始学习克隆之前,我们先来看看下面的代码,普通的对象复制,存在什么问题? class CloneTest {public static void main(String[] args) throws CloneNotSupportedException {// 等号赋值( 基本类型)int number = 6;int number2 = number;// 修改 number2 的值num…

Java StreamTokenizer whitespaceChars()方法及示例

StreamTokenizer类whitespaceChars()方法 (StreamTokenizer Class whitespaceChars() method) whitespaceChars() method is available in java.io package. whitespaceChars()方法在java.io包中可用。 whitespaceChars() method is used to denotes that all the characters l…

Oracle-1 / Oracle及PlsqlDeveloper的设置

1、启动监听器与服务器我的电脑->管理->服务...保证“...listener...”和“...service...”两个服务开启2、客户端软件设置tools->preference->connection->Oracle home设置好Oracle所在的路径3、监听列表设置在Oracle安装目录下找到network文件夹两个文件时 li…

远程拍照并获取图片

主要功能 肉鸡程序启动后可打开摄像头迅速拍摄一张照片&#xff0c;通过服务器发送到主机&#xff0c;发送完成后删除肉鸡本地保存的图片 相关技术 socket网络编程文件操作opencv 代码 肉鸡 #define _WINSOCKAPI_ #define _CRT_SECURE_NO_WARNINGS #define _WINSOCK_DE…

第 2-3 课:抽象类和接口 + 面试题

抽象类 定义 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。简单来说,使用关键字 abstract 修饰的类就叫做抽象类。 抽象类使用 示例代码…

CentOS 6.4下操作kdump执行过程

kdump 是一个新的&#xff0c;而且非常可信赖的内核崩溃转储机制。崩溃转储数据可以从一个新启动的内核的上下文中获取&#xff0c;而不是从已经崩溃的内核的上下文。当系统崩溃时&#xff0c;kdump使用kexec启动到第二个内核。第二个内核通常叫做捕获内核&#xff08;capture …

java jar包示例_Java包getSpecificationVersion()方法和示例

java jar包示例包类的getSpecificationVersion()方法 (Package Class getSpecificationVersion() method) getSpecificationVersion() method is available in java.lang package. getSpecificationVersion()方法在java.lang包中可用。 getSpecificationVersion() method is us…

JAVA类(手机充电、放音乐示例)

练习练习 import java.util.Scanner;//包含包public class ex1 {public static void main(String args[])//程序入口{Phone phone new Phone();//建一个手机phone.logo "SONY";//弄上个牌子phone.battery.power 100;//给电池弄上100电Scanner reader new Scanner…

linux——进程(创建、终止、等待、替换)

进程的基本操作 概念 程序运行的一个实例&#xff0c;其占有一定的空间。 查询某一进程当前情况 ps aux | grep 进程名终止进程 kill -9 pid&#xff1b; //pid指需要终止的进程pid创建 pid_t fork();该函数有两个返回值&#xff0c;对于子进程其返回的是0&#xf…

第 3-1 课:集合详解(上) + 面试题

先来看看集合的继承关系图,如下图所示: 其中: 外框为虚线的表示接口,边框为实线的表示类;箭头为虚线的表示实现了接口,箭头为实线的表示继承了类。为了方便理解,我隐藏了一些与本文内容无关的信息,隐藏的这些内容会在后面的章节中进行详细地介绍。 从图中可以看出,集…

Java类class isAnnotationPresent()方法与示例

类类isAnnotationPresent()方法 (Class class isAnnotationPresent() method) isAnnotationPresent() method is available in java.lang package. isAnnotationPresent()方法在java.lang包中可用。 isAnnotationPresent() method returns true when the annotation for the gi…

CCNA 学习笔记(四)--路由协议(RIP)

现在我们先复习下&#xff0c;什么是路由&#xff1f;答&#xff1a;当路由器&#xff08;或者其它三层设备&#xff09;收到一个IP数据包时&#xff0c;会查看数据包的IP头部中的目的IP地址&#xff0c;并在路由表中进行查找&#xff0c;在匹配到最优路由后&#xff0c;将数据…

第 3-3 课:泛型和迭代器 + 面试题

泛型 1)为什么要用泛型? 在泛型没有诞生之前,我们经常会遇到这样的问题,如以下代码所示: ArrayList arrayList = new ArrayList(); arrayList.add("Java"); arrayList.add(24); for (int i = 0; i < arrayList.size(); i++) {String str = (String) array…

自连接 实例

SELECT * FROM student_grade;select t1.num,t1.name,t1.chinese,t2.math,t3.english from (SELECT a.num,a.name,a.sex,b.grade as chinese FROM student_grade as ainner join student_grade as b on a.num b.num and a.course b.coursewhere b.course 语文) as t1,(SELEC…

linux——进程间通信(管道)

概念 进程间通信是指子进程与父进程间的通信&#xff0c;一般用作父进程对子进程的控制或者子进程将其动向告诉父进程&#xff0c;由于进程是一个程序执行的实例&#xff0c;进程之间本身是无法进行通信的&#xff0c;故而运用一种管道将二者联系起来。当然管道并不只限于在父子…