在线词典。

2021/7/25 23:50:39

本文主要是介绍在线词典。,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

在线词典实现框架:

在这里插入图片描述

1、在线词典

2、项目功能描述

3、用户注册和登录验证

4、服务器端将用户信息和历史记录保存在数据库中,客户端输入用户名和密码,服务器端在数据库中查找、匹配,返回结果

5、单次在线翻译

6、根据客户端输入的单次在字典文件中搜索

7、历史记录查询

8、项目分析

服务器流程图:

在这里插入图片描述

客户端流程图:

在这里插入图片描述

/*server*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <sqlite3.h>
#include <signal.h>
#include <time.h>

#define N 128

#define R 1  //register
#define L 2  //login
#define O 3  //logout
#define M 4  //modify
#define Q 5  //query
#define H 6  //history record
#define DATABASE "my.db"

typedef struct {

	int  type;      //类型
	char name[N];   //用户名
	char data[256]; //密钥
	int  flag;      //标识位

}MSG;
//客户端请求处理函数
int do_client(int rws, sqlite3 *db);
//注册处理函数
int do_register(int rws, MSG *msg, sqlite3 *db);
//登录处理函数
int do_login(int rws, MSG *msg, sqlite3 *db);
//注销处理函数
int do_logout(int rws, MSG *msg, sqlite3 *db);
//修改信息函数
int do_modify(int rws,MSG *msg,sqlite3 *db);
//查询单词函数
int do_query(int rws,MSG *msg,sqlite3 *db);
//显示查询记录函数
int do_record(int rws,MSG *msg,sqlite3 *db);


// ./server 192.168.30.202 8888
int main(int argc, const char *argv[])
{

	int s = -1;  //监听套接字
	int rws =-1; //读写套接字
	struct sockaddr_in addr;
	char *errmsg;
	pid_t pid;
	//命令行传参	
	if(argc != 3){
		printf("Usage: %s <ipstr> <port>.\n", argv[0]);
		return -1;
	}	

	//1.创建套接字
	if((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	{
		perror("socket");
		return -1;
		//	exit(-1);
	}

	//2.初始化服务器端地址结构体
	//bzero(&addr, sizeof(addr));
	memset(&addr,0,sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = inet_addr(argv[1]);
	addr.sin_port = htons(atoi(argv[2]));

	//3.绑定IP和端口
	if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0)
	{
		perror("bind");
		goto ERR_STEP;
		//return -1;
		//exit(-1);
	}

	//4.监听套接字
	if(listen(s, 10) < 0)
	{
		perror("listen");
		goto ERR_STEP;
		//exit(-1);
	}

	//5.设置套接字端口复用属性
	int on = 1;
	//setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
	if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
	{
		perror("setsockopt");
		return -1;
	}
	//创建打开数据库
	sqlite3 *db;
	if(sqlite3_open(DATABASE, &db) != SQLITE_OK)
	{
		printf("%s\n", sqlite3_errmsg(db));
		return -1;
	}
	else
	{
		printf("open Database success\n");
	}
	//需要在数据库中创建两张表:学生信息表和查询记录表
	//创建学生信息表
	//char sql[256]="create table if not exists stu(id integer primary key autoincrement, name text,passwd text);";
	char sql[256]="create table if not exists stu(name text,passwd text);";
	printf("sql=%s\n",sql);//调试信息
	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=0)
	{
		fprintf(stderr,"create table fail! %s\n",errmsg);
		return -1;
	}
	//创建历史记录信息表
	char sql_history[256]="create table if not exists record(name text,datetime text,word text);";
	printf("sql_history=:%s\n",sql_history);//调试信息
	if(sqlite3_exec(db,sql_history,NULL,NULL,&errmsg)!=0)
	{
		fprintf(stderr,"create table fail! %s\n",errmsg);
		return -1;
	}
	printf("-------------------准备事项均已成功创建!-------------------------\n");
	printf("-------------------接下来等待客户链接请求-------------------------\n");

	//父进程接收子进程的退出信号
	signal(SIGCHLD, SIG_IGN);

	//6.循环处理客户端的链接服务请求
	while(1)
	{
		printf("wait for client...\n");
#if 0
		/*如需打印连接的客户端信息,则开启此段代码*/
		struct sockaddr_in cliaddr;
		socklen_t clilen=sizeof(cliaddr);
		rws=accept(s,(struct sockaddr*)&cliaddr,&clilen);
		//if(0 >(rws=accept(s,(struct sockaddr*)&cliaddr,&clilen));
		char buf[INET_ADDRSTRLEN]={};
		if(inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,buf,INET_ADDRSTRLEN))
		{
			printf("client ip:%s ",buf);
		}
		printf("port:%u\n",ntohs(cusaddr.sin_port));
#endif
#if 1
		if((rws = accept(s, NULL, NULL)) < 0)
		{
			perror("accept");
			exit(-1);
		}
#endif
		//调用fork函数创建子进程
		if((pid = fork()) < 0)
		{
			perror("fork");
			exit(-1);
		}
		else if(pid == 0)
		{
			//子进程负责处理客户端发来的链接请求
			close(s);                       //不需要监听套接字,关闭
			do_client(rws, db);             //处理函数,传参读写套接字以及数据库句柄

		}
		else
		{

			//父进程负责接收客户请求
			close(rws);                    //关闭读写套接字
		}
	}
ERR_STEP:
	close(s);
	close(rws);
	return 0;
}
//处理客户端请求函数
int do_client(int rws, sqlite3 *db)
{
	MSG msg;                              //定义信息结构体变量
	//客户端先发送链接请求信息
	//服务器接收客户端的请求信息,并按照双方协议,判断客户端请求的类型
	while(recv(rws, &msg, sizeof(msg), 0) > 0)
	{
		//根据结构体中请求类型变量,调用响应的子程序进行处理
		switch(msg.type)
		{
		case R:
			do_register(rws, &msg, db);   //注册,传参读写套接字,结构体地址,数据库句柄
			break;
		case L:
			do_login(rws, &msg, db);      //登录,传参读写套接字,结构体地址,数据库句柄
			break;
		case O:
			do_logout(rws,&msg,db);       //注销
			break;
		case M:
			do_modify(rws,&msg,db);       //修改
			break;
		case Q:
			do_query(rws,&msg,db);        //查询
			break;
		case H:
			do_record(rws,&msg,db);       //回查
			break;
		default:                          //其他
			printf("Invalid msg.\n");
			break;
		}
	}
	printf("Client is leave...\n");
	close(rws);
	exit(0);                              //退出时,发送SIGCHLD信号,父进程设置忽略处理
}
//注册处理函数
int  do_register(int rws, MSG *msg, sqlite3 *db)
{
	char * errmsg;
	char sql[128];
	//查重
	//char *errmsg;
	int nrow, ncloumn;                         //数据库行数和列数
	char **resultp;                            //定义二级指针保存SOL语句执行的结果
	//拼接SOL语句,查询用户名和密码与数据库内容是否匹配
	sprintf(sql, "select * from stu where name='%s';", msg->name);
	printf("%s\n", sql);                        //调试语句,打印SQL语句信息
	//无回调函数版的,返回调用一个命令的整个结果集
	if(sqlite3_get_table(db, sql, &resultp, &nrow, &ncloumn, &errmsg) != SQLITE_OK)
	{
		printf("%s\n", errmsg);
		return -1;
	}
	else
	{
		printf("get_table ok!\n");
	}

	//调用传参行数,判断是否查找到用户信息,若有则代表已注册,否则可以注册
	if(nrow == 1)
	{
		strcpy(msg->data, "REPEAT");
		send(rws, msg, sizeof(MSG), 0);          //发送匹配成功信息,证明有重复账号
		return 1;
	}
	else
	{
		//拼接SQL语句,将客户端的姓名和密码加入添加到数据库
		sprintf(sql, "insert into stu values('%s', %s);", msg->name, msg->data);
		printf("%s\n", sql);                     //调试语句,打印sql语句内容
		if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)//便捷函数返回异常,代表注册失败,注册名已存在
		{
			printf("%s\n", errmsg);
			strcpy(msg->data, "invaild input or stu name already exist.");  //将注册错误信息填写至结构体信息成员,待返回客户端
		}
		else
		{
			printf("client register ok!\n");     //成功
			strcpy(msg->data, "ok!");            //成功信息填写至结构体信息成员,待返回客户端
		}
		if(send(rws, msg, sizeof(MSG), 0) < 0)   //发送信息至客户端,待客户反馈
		{
			perror("send");
			return -1;
		}
	}
	return 0;
}
//登录处理函数
int do_login(int rws, MSG *msg, sqlite3 *db)
{
	char sql[128] = {};
	char *errmsg;
	int nrow, ncloumn;                           //数据库行数和列数
	char **resultp;                              //定义二级指针保存SOL语句执行的结果
	//拼接SOL语句,查询用户名和密码与数据库内容是否匹配
	sprintf(sql, "select * from stu where name='%s' and passwd='%s';", msg->name, msg->data);
	printf("%s\n", sql);                         //调试语句,打印SQL语句信息
	//无回调函数版的,返回调用一个命令的整个结果集
	if(sqlite3_get_table(db, sql, &resultp, &nrow, &ncloumn, &errmsg) != SQLITE_OK)
	{
		printf("%s\n", errmsg);
		return -1;
	}
	else
	{
		printf("get_table ok!\n");
	}

	//调用传参行数,判断是否查找到用户信息,若有则代表成功,否则输入错误或用户不存在
	if(nrow == 1)
	{
		strcpy(msg->data, "OK");
		msg->flag=1;                           //登录成功,设置标识位为1
		send(rws, msg, sizeof(MSG), 0);        //发送匹配成功信息
		return 1;
	}
	else
	{
		strcpy(msg->data, "usr/passwd wrong.");
		send(rws, msg, sizeof(MSG), 0);        //发送匹配失败信息
	}

	return 0;
}
//注销处理子函数
int do_logout(int rws, MSG *msg, sqlite3 *db)
{
	char * errmsg;
	char sql[128];
	//拼接SQL语句,以客户端登录姓名为关键字,从数据库中将整条信息删除
	//	sprintf(sql, "insert into usr values('%s', %s);", msg->name, msg->data);
	sprintf(sql, "delete from stu where name='%s';", msg->name);
	printf("%s\n", sql);                       //调试语句,打印sql语句内容
	if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)       //便捷函数返回异常,代表注销失败
	{
		printf("%s\n", errmsg);
		strcpy(msg->data, "stu name input error.");                     //将注销错误信息填写至结构体信息成员,待返回客户端
	}
	else
	{
		printf("client logout ok!\n");          //成功
		strcpy(msg->data, "ok!");               //成功注销信息,待返回客户端
	}
	if(send(rws, msg, sizeof(MSG), 0) < 0)      //发送信息至客户端,待客户反馈
	{
		perror("send");
		return -1;
	}
	return 0;
}
//修改信息子函数
int do_modify(int rws,MSG *msg,sqlite3 *db)
{
	char * errmsg;
	char sql[128];

	//拼接SQL语句,将要修改的内容内容传入SQL语句中
	sprintf(sql,"update stu set passwd='%s' where name='%s';",msg->data,msg->name);
	printf("%s\n", sql);//调试语句,打印sql语句内容
	if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK) //便捷函数返回异常,代表修改失败
	{
		printf("%s\n", errmsg);
		strcpy(msg->data, "stu  passwd modify fail.");          //将修改未成功信息填写至结构体信息成员,待返回客户端
	}
	else
	{
		printf("stu passwd modify ok!\n");                      //成功
		strcpy(msg->data, "ok!");                               //成功信息填写至结构体信息成员,待返回客户端
	}
	if(send(rws, msg, sizeof(MSG), 0) < 0)                      //发送信息至客户端,待客户反馈
	{
		perror("send");
		return -1;
	}

	return 0;
}
//查词函数(只负责查找,并返回查询函数结果,由查询函数最终向客户端反馈结果,查词成功还要向数据库插入数据)
int do_searchword(int rws,MSG*msg,char *word)
{
	//打开本地的词典文件,词典打开失败也要通知客户端
	FILE* fp=fopen("./dict.txt","r");
	if(NULL==fp)
	{
		perror("fopen failure");
		strcpy(msg->data,"open dict.txt failure");
		if(0 >send(rws,msg,sizeof(MSG),0))
		{
			perror("send");
			goto ERR_STEP;
			//	return -1;
		}
		//打开成功,则需要比较词典中有无参数中的单词
	}
	printf("word is %s,word len is %d\n",word,strlen(word));//调试信息
#define MAXSIZE 1024
	char buf[MAXSIZE]={};
	while(1)
	{ 
		while(fgets(buf,MAXSIZE,fp))
		{
			int ret=strncmp(buf,word,strlen(word));
			if(0 > ret)
				continue;                //当前单词比要找单词小,继续
			else if( 0 < ret)            //当前单词比要找单词大,因为单词表是按ASCII码的顺序排序的,后面的单词ASCII更大,所以就是没找到
				goto ERR_STEP;
			//	return -1;
			else if((0==ret) && (buf[strlen(word)]!=' '))  //当前单词和要找单词在前n个字节一致,但词典中该词在长度n后面还有内容,也不是要找的内容
				goto ERR_STEP;
			//	return -1;
			else                         //除以上情况外,就是找到了,找打了就把名词解释发送给客户
			{
				//此处难点是如何找到名词解释在哪里?
				//查看词典格式如下:abandonment      n.  abandoning
				//1.根据单词格式可以看出,名词解释的地址,就是在“单词+空格后的第一个非空字符”的地址
				//2.所以应定义一个指针,最终可以指向这个地址
				//   ①跨过单词
				//   ②跨过空格
				char *ptext;
				ptext=buf+strlen(word);
				while(*ptext==' ')
					ptext++;
				//正文复制到信息结构体中
				strcpy(msg->data,ptext);        
				printf("word find:%s",msg->data); //调试信息
				goto ERR_STEP1;
			}
		}
		if(feof(fp))
			break;
	}
ERR_STEP1:
	fclose(fp);
	return 0;
ERR_STEP:
	fclose(fp);
	return -1;
}
char* gettime()
{
	time_t time_now;
	struct tm *t;
	time_now=time(NULL);
	t=localtime(&time_now);
	return asctime(t);
}

//查询单词函数
int do_query(int rws,MSG *msg,sqlite3 *db)
{
	//接收客户端传来的单词
	//检索该单词是否存在于本地文件或数据库中
	//单词存在:
	//1.则从文件或数据库中取词,放到信息结构体中发送至客户端(关键)
	//2.把该单词和客户端姓名、查询时间信息放到数据库表record中(难点)
	//单词不存在,则发送“单词未找到信息反馈到客户端”
	//鉴于以上查询单词操作的分类情况和复杂度,应单独封装函数进行处理,用返回值区分单词存在还是不存在


	//定义buf接收单词
	char word[256]={};
	char * errmsg;
	char time[256]={};
	strcpy(word,msg->data);
	char sql_message[256]={};
	int ret=do_searchword(rws,msg,word);
	if(0>ret)
	{
		//查询失败信息填入信息结构体
		strcpy(msg->data,"This word cannot be found");
	}
	else
	{
		//拼接,把查询记录添加到record数据表中
		strcpy(time,gettime());
		sprintf(sql_message,"insert into record values('%s','%s','%s');",msg->name,time,word);
		printf("sql_message:%s\n",sql_message);
		if(sqlite3_exec(db,sql_message,NULL,NULL,&errmsg)!=SQLITE_OK)
		{
			printf("%s\n", errmsg);
			strcpy(msg->data, "query success,buf server SQL entry failure");  //将查询信息录入失败信息填写至结构体信息成员,待返回客户端
		}
	//	return -1;
	}
	if(0 > send(rws,msg,sizeof(MSG),0))
	{
		perror("send");
		return -1;
	}
	printf("message:%s\n",msg->data);

	return 0;
}
//回调函数
int record_callback(void *para,int f_num,char **f_value,char **f_name)
{
	int rws;
	MSG msg;
	rws=*(int *)para;
	sprintf(msg.data,"%s  %s  %s",f_value[0],f_value[1],f_value[2]);
	if(0 > send(rws,&msg,sizeof(MSG),0))
	{
		perror("send");
		return -1;
	}
	return 0;
}
//显示查询记录函数
int do_record(int rws,MSG *msg,sqlite3 *db)
{
	char sql[256]={};
	char *errmsg;

	sprintf(sql,"select *from record where name='%s';",msg->name);
	printf("sql=%s\n",sql);
	if(sqlite3_exec(db,sql,record_callback,(void*)&rws,&errmsg)!=SQLITE_OK)
	{
		printf("%s\n",errmsg);
		strcpy(msg->data, "History record query failure");  //将查询信息录入失败信息填写至结构体信息成员,待返回客户端
	}
	else
		printf("query successful.\n");
	msg->data[0]='\0';
	if(0 > send(rws,msg,sizeof(MSG),0))
	{
		perror("send");
		return -1;
	}
	return 0;
}

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

#define N 128
//双方约定相同的信号定义
#define R 1  //register
#define L 2  //login
#define O 3  //logout
#define M 4  //modify
#define Q 5  //query
#define H 6  //history recond

typedef struct {
	int  type;
	char name[N];
	char data[256];
	int  flag;
}MSG;
//注册子函数
int do_register(int sockfd, MSG *msg)
{
	//输入姓名
	msg->type = R;
	printf("Input name:");
	scanf("%s", msg->name);
	getchar();
	//输入密码
	printf("Input passwd:");
	scanf("%s", msg->data);
	getchar();
	//客户端先发送
	if(send(sockfd, msg, sizeof(MSG), 0) < 0)
	{
		printf("fail to send.\n");
		return -1;
	}
	//客户端后接收
	if(recv(sockfd, msg, sizeof(MSG), 0) < 0)
	{
		printf("fail to recv.\n");
		return -1;
	}
	//没有退出就是注册成功!
	//ok! or usr already exist.
	printf("%s\n", msg->data);

	return 0;
}
//登录子函数
int do_login(int sockfd, MSG *msg)
{
	//输入姓名
	msg->type = L;
	printf("Input name:");
	scanf("%s", msg->name);
	getchar();
	//输入密码
	printf("Input passwd:");
	scanf("%s", msg->data);
	getchar();
	//发送登录信息
	if(send(sockfd, msg, sizeof(MSG), 0) < 0)
	{
		printf("fail to send.\n");
		return -1;
	}
	//接收服务器反馈
	if(recv(sockfd, msg, sizeof(MSG), 0) < 0)
	{
		printf("fail to recv.\n");
		return -1;
	}
	//返回ok代表登录成功
	if(strncmp(msg->data, "OK", 3) == 0)
	{
		printf("Login OK!\n");
		return 1;
	}
	//否则打印错误信息
	else
	{
		printf("%s\n", msg->data);
		return 0;
	}

	return 0;
}
//注销子函数
int do_logout(int sockfd, MSG *msg)
{
	if(msg->flag==0)
	{
		printf("Not logged in yet\n ");
		return -1;
	}
	//输入姓名
	msg->type = O;
#if 0
	printf("Input name:");
	scanf("%s", msg->name);
	getchar();
	//输入密码
	printf("Input passwd:");
	scanf("%s", msg->data);
#endif
	//客户端先发送
	if(send(sockfd, msg, sizeof(MSG), 0) < 0)
	{
		printf("fail to send.\n");
		return -1;
	}
	//客户端后接收
	if(recv(sockfd, msg, sizeof(MSG), 0) < 0)
	{
		printf("fail to recv.\n");
		return -1;
	}
	printf("%s\n", msg->data);

	return 0;
}
//修改子函数
int do_modify(int sockfd, MSG *msg)
{
	if(msg->flag==0)
	{
		printf("Not logged in yet\n ");
		return -1;
	}
	msg->type = M;
#if 0
	printf("Input name:");
	scanf("%s", msg->name);
	getchar();
#endif
#if 1
	//输入密码
	printf("Input newpasswd:");
	scanf("%s", msg->data);
	getchar();
#endif
	//客户端先发送
	if(send(sockfd, msg, sizeof(MSG), 0) < 0)
	{
		printf("fail to send.\n");
		return -1;
	}
	//客户端后接收
	if(recv(sockfd, msg, sizeof(MSG), 0) < 0)
	{
		printf("fail to recv.\n");
		return -1;
	}
	printf("%s\n", msg->data);
	return 0;
}
int do_query(int sockfd,MSG *msg)
{
	msg->type=Q;
	while(1)
	{
		//输入要查询的单词,缓存接收单词
		printf("please input a word:");
		if(!fgets(msg->data,sizeof(msg->data)-1,stdin))
		{
			printf("input error.\n");
			return -1;
		}
		msg->data[strlen(msg->data)-1]='\0';
		if(0==strncmp(msg->data,"&",1))
			break;
		//通过套接字将单词传给客户端(先发)
		if(send(sockfd,msg,sizeof(MSG),0)<0)
		{
			printf("fail to send.\n");
			return -1;
		}
		//接收服务器反馈,打印
		if(recv(sockfd,msg,sizeof(MSG),0)<0)
		{
			printf("fail to recv.\n");
			return -1;
		}
		printf("%s\n",msg->data);
	}
	return 0;
}
int do_recond(int sockfd,MSG*msg)
{ 
	msg->type=H;
	if(send(sockfd,msg,sizeof(MSG),0) <0)
	{
		printf("fail to send.\n");
		return -1;
	}
	while(1)
	{
		if(recv(sockfd,msg,sizeof(MSG),0)<0)
		{
			printf("fail to recv.\n");
			return -1;
		}
		if(msg->data[0]==0)  //按约定退出
			break;            
		printf("%s\n",msg->data);
	}
	return 0;
}
//./client 192.168.30.202 8888
int main(int argc, const char *argv[])
{
	int sockfd = -1;
	struct sockaddr_in sin;
	MSG msg;
	memset(&msg,0,sizeof(msg));
	int n;
	//命令行传参
	if(argc != 3){
		printf("Usage: %s <servip> <port>.\n", argv[0]);
		return -1;
	}
	//1.创建套接字
	if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
		perror("socket");
		exit(-1);
	}

	//2.初始化服务器地址结构体信息
	bzero(&sin, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = inet_addr(argv[1]);
	sin.sin_port = htons(atoi(argv[2]));

	if(connect(sockfd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
	{
		perror("connect");
		exit(-1);
	}
	//循环向服务器端发送客户端链接请求,并把交互设计在客户端,服务器只是对客户端请求的应答
	/* ----------------设计协议: 1.客户端请求:注册,登录,退出-----------------*/
next1:
	while(1)
	{

		printf("*****************************************\n");
		printf("*   1:register     2.login     3:quit   *\n");
		printf("*****************************************\n");
		printf("Please choose:");//选号,按号实现响应功能代码
		char buf[256]={};

		if(fgets(buf,256,stdin))
		{
			int size=strlen(buf);
			printf("len=%d\n",size);
			//	int num=buf[0]-'0';
			//  printf("num=%d\n",num);
			//	buf[strlen(buf)-1]='\0';
			if(strlen(buf)==2)
			{
				int num=buf[0]-'0';
				printf("num=%d\n",num);
				if((!((num >= 1)&&(num <=3)))&&(strlen(buf)!='\n'))
				{
					printf("choose input Invalid,please enter again.\n");
					continue;
				}
			}
			else
			{
				printf("choose input Invalid,please enter again.\n");
				continue;
			}
		}
#if 0
		scanf("%d", &n);
		getchar(); //吃垃圾字符

		if(!((n >= '1')&&(n <='3')))
		{
			printf("choose input Invalid,please enter again.\n");
			continue;
		}
#endif
		switch(buf[0]-'0')
		{
		case 1:
			do_register(sockfd, &msg);      //注册子函数
			break;
		case 2:
			if(do_login(sockfd, &msg) == 1) //登录子函数
			{
				goto next;
			}
			break;
		case 3:                              //退出子函数
			close(sockfd);
			exit(0);
			break;
		default:                            //命令错误
			printf("Invalid data cmd.\n");
		}
	}

next:
	while(1)
	{
		printf("**********************************************\n");
		printf("*   1:logout     2:modify     3:return menu  *\n");
		printf("*          4:query        5:record           *\n");
		printf("**********************************************\n");
		printf("Please choose:");
#if 1
		char buf[256]={};

		if(fgets(buf,256,stdin))
		{
			int size=strlen(buf);
			printf("len=%d\n",size);
			//	int num=buf[0]-'0';
			//  printf("num=%d\n",num);
			//	buf[strlen(buf)-1]='\0';
			if(strlen(buf)==2)
			{
				int num=buf[0]-'0';
				printf("num=%d\n",num);
				if((!((num >= 1)&&(num <=5)))&&(strlen(buf)!='\n'))
				{
					printf("choose input Invalid,please enter again.\n");
					continue;
				}
			}
			else
			{
				printf("choose input Invalid,please enter again.\n");
				continue;
			}
		}
#endif
#if 0
		scanf("%d", &n);
		getchar();
		if(!((n >= '1')&&(n <='5')))
		{
			printf("choose input Invalid,please enter again.\n");
			continue;
		}
#endif
		switch(buf[0]-'0'){
		case 1:
			do_logout(sockfd, &msg);
			break;
		case 2:
			do_modify(sockfd,&msg);
			break;
		case 3:
			goto next1;
			//	break;
		case 4:
			do_query(sockfd,&msg);
			break;
		case 5:
			do_recond(sockfd,&msg);
			break;
		default:
			printf("Invalid data cmd.\n");
		}
	}
	return 0;
}

希望看到此文章的小伙伴们,如果有什么错误,欢迎下方留言,博客肯定虚心接受并改正!大家一起共同进步。如果对你有所帮助,可以给博主一个小小的赞



这篇关于在线词典。的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程