电子词典dictionary

news2024/11/20 2:43:13

一、项目要求:

     1.登录注册功能,不能重复登录,重复注册。用户信息也存储在数据库中。

     2.单词查询功能

     3.历史记录功能,存储单词,意思,以及查询时间,存储在数据库

     4.基于TCP,支持多客户端连接

     5.采用数据库保存用户信息与历史记录

     6.将dict.txt的数据导入到数据库中保存。

     7.返回上级、按下ctrl+c退出客户端后,该用户退出登录

二、格式要求:

     1.main函数只跑逻辑,不允许跑功能代码

     2.功能代码封装成函数

三、项目功能:

     1.注册

     2.登录

     3.查询单词

     4.查看历史记录

     5.退出登录

四、框架设计:

4.1服务器设计 

4.2客户端设计

五、功能说明:

5.1用户注册

      输入用户名和密码,插入用户表中,用户名不能和已有用户名字冲突,否则失败。

5.2用户登录

      输入用户名和密码,通过遍历表中数据,核对数据信息,成功,转到第二个操作界面。

5.3查询单词

      输入单词,在词典文件中查找,存在得到单词解释,并且将查询记录保存到记录表中。

5.4查询历史记录

      遍历记录表中数据,将用户查询的时间和单词打印到终端上。

5.5多进程实现TCP并发

六、具体代码:

head.h:

#ifndef __HEAD_H__
#define __HEAD_H__

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


#define PORT 8808
#define IP "127.0.0.1"
#define ERR_MSG(msg) { fprintf(stderr,"__%d__",__LINE__); perror(msg); }

int put_dict(sqlite3 *db);
void handler(int sig);
int do_register(sqlite3 *db,char *buf);
void do_register_cli(char *buf);
int Register(sqlite3 *db,char *buf);
void do_login(char *buf);
int Login(sqlite3 *db,char *buf);
int do_select_user(sqlite3 *db,char *name);
int do_insert(sqlite3 *db,char *words,char *mean,char *save_buf);
int Search(sqlite3 *db,char *buf,char *save_buf);
int Search_res(sqlite3 *db,char *buf,char *save_buf);
int deal_cli_msg(int newfd,struct sockaddr_in cin,sqlite3 *db);

#endif

dictionary.c(功能函数):

#include "head.h"

//导入词典
int put_dict(sqlite3 *db)
{
	//创建并打开一个数据库
	if(sqlite3_open("./dict.db",&db) != SQLITE_OK)
	{
		printf("sqlite3_open:%s %d __%d__\n",\
				sqlite3_errmsg(db),sqlite3_errcode(db),__LINE__);
		return -1;
	}

	//创建一个表格 create table stu (id int,name char,score float);
	//数据库中sql语句怎么写,这里就怎么写
	char sql[128] = "create table dict (word char,mean char);";
	char* errmsg = NULL;

	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"sqlite3_open:%s %d __%d__\n",\
				errmsg,sqlite3_errcode(db),__LINE__);
		return -1;
	}

	//打开文件
	FILE* fp = fopen("./dict.txt","r");
	if(NULL == fp)
	{
		perror("fopen");
		return -1;
	}

	//循环读取文件中的数据,一行一行的读取
	char buf[256] = "";
	char word[32] = "";
	char mean[200] = "";
	int count = 1;
	int i =0;
	char* ptr = NULL;

	while(1)
	{
		if(fgets(buf,sizeof(buf),fp) == NULL)
			break;
		buf[strlen(buf)-1] = 0;

		//分离单词和意思
		bzero(word,sizeof(word));
		bzero(mean,sizeof(mean));

		//获取" "子串在buf中的地址
		ptr = strstr(buf," ");
		if(NULL == ptr)
		{
			printf("没有找到对应子串\n");
			break;
		}
		strncpy(word,buf,ptr-buf);    //" "子串前面是单词
		strcpy(mean,ptr+3);           //" "子串后面是意思

		//插入到数据库中
		sprintf(sql,"insert into dict values(\"%s\",\"%s\");",word,mean);
		if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
		{
			printf("sqlite3_exec failed:%s __%d__\n",errmsg,__LINE__);
			return -1;
		}
	}
	printf("数据库建立成功\n");

	//关闭文件
	fclose(fp);
	//关闭数据库
	if(sqlite3_close(db) != SQLITE_OK)
	{
		fprintf(stderr,"sqlite3_close:%s %d __%d__\n",\
				sqlite3_errmsg(db),sqlite3_errcode(db),__LINE__);
		return -1;
	}
	return 0;
}

//捕获信号
void handler(int sig)
{
	while(waitpid(-1, NULL, WNOHANG) > 0);
}

//实现注册功能
int do_register(sqlite3 *db,char *buf)
{
	//打开数据库
	if(sqlite3_open("./dict.db",&db) != SQLITE_OK)
	{
		fprintf(stderr,"sqlite3_open: %s __%d__\n",sqlite3_errmsg(db),__LINE__);
		return -1;
	}

	//创建一个表
	char sql[128] = "create table if not exists user (name char,passwd char);";
	char *errmsg = NULL;

	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"sqlite3_exec: %s __%d__\n",errmsg,__LINE__);
		return -1;
	}

	char *name = buf+2;
	char *passwd = buf+2+strlen(buf+2)+1;

	if(do_select_user(db,name) == 1)
	{
		if(sqlite3_close(db) != SQLITE_OK)
		{
			printf("sqlite3_close failed:%s __%d__\n", sqlite3_errmsg(db), __LINE__);
			return -1;
		}
		return 1;
	}
	sprintf(sql,"insert into user values ('%s','%s');",name,passwd);
	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"sqlite3_exec: %s __%d__\n",errmsg,__LINE__);
		return -1;
	}
	printf("register success...\n");

	//关闭数据库,释放对应的内存空间
	if(sqlite3_close(db) != SQLITE_OK)
	{
		printf("sqlite3_close failed:%s __%d__\n", sqlite3_errmsg(db), __LINE__);
		return -1;
	}
	return 0;
}

//客户端注册函数
void do_register_cli(char *buf)
{
	char name[32] = "";
	char passwd[32] = "";
	printf("请输入您的用户名>>>");
	scanf("%s",name);
	getchar();
	printf("请输入您的密码>>>");
	scanf("%s",passwd);
	getchar();
	sprintf(buf,"%s%c%s%c%s","1",0,name,0,passwd);
}

//实现注册功能
int Register(sqlite3 *db,char *buf)
{
	//打开数据库
	if(sqlite3_open("./dict.db",&db) != SQLITE_OK)
	{
		fprintf(stderr,"sqlite3_open: %s __%d__\n",sqlite3_errmsg(db),__LINE__);
		return -1;
	}

	//创建一个表
	char sql[128] = "create table if not exists user (name char,passwd char);";
	char *errmsg = NULL;

	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"sqlite3_exec: %s __%d__\n",errmsg,__LINE__);
		return -1;
	}

	char *name = buf+2;
	char *passwd = buf+2+strlen(buf+2)+1;

	if(do_select_user(db,name) == 1)
	{
		if(sqlite3_close(db) != SQLITE_OK)
		{
			printf("sqlite3_close failed:%s __%d__\n", sqlite3_errmsg(db), __LINE__);
			return -1;
		}
		return 1;
	}
	sprintf(sql,"insert into user values ('%s','%s');",name,passwd);
	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"sqlite3_exec: %s __%d__\n",errmsg,__LINE__);
		return -1;
	}
	printf("register success...\n");

	//关闭数据库,释放对应的内存空间
	if(sqlite3_close(db) != SQLITE_OK)
	{
		printf("sqlite3_close failed:%s __%d__\n", sqlite3_errmsg(db), __LINE__);
		return -1;
	}
	return 0;
}

//登录函数
void do_login(char *buf)
{
	char name[32] = "";
	char passwd[32] = "";

	printf("请输入用户名>>>");
	scanf("%s",name);
	getchar();
	printf("请输入密码>>>");
	scanf("%s",passwd);
	getchar();
	sprintf(buf,"%s%c%s%c%s","2",0,name,0,passwd);
}

//实现登录功能
int Login(sqlite3 *db,char *buf)
{
	//打开数据库
	if(sqlite3_open("./dict.db",&db) != SQLITE_OK)
	{
		fprintf(stderr,"sqlite3_open: %s __%d__\n",sqlite3_errmsg(db),__LINE__);
		return -1;
	}

	char sql[128] = "create table if not exists user (name char,passwd char);";
	char *errmsg = NULL;

	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"sqlite3_exec: %s __%d__\n",errmsg,__LINE__);
		return -1;
	}

	strcpy(sql,"select * from user;");
	char **pres = NULL;
	int row,column;
	if(sqlite3_get_table(db,sql,&pres,&row,&column,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"sqlite3_exec: %s __%d__\n",errmsg,__LINE__);
		return -1;
	}

	char *name = buf+2;
	char *passwd = buf+2+strlen(buf+2)+1;

	for(int i=2;i<(row+1)*column;i++)
	{
		if(strcmp(pres[i],name) == 0 && strcmp(pres[i+1],passwd) == 0)
		{
			printf("login success...\n");
			if(sqlite3_close(db) != SQLITE_OK)
			{
				printf("sqlite3_close failed:%s __%d__\n", sqlite3_errmsg(db), __LINE__);
				return -1;
			}
			return 2;
		}
	}

	//关闭数据库,释放对应的内存空间
	if(sqlite3_close(db) != SQLITE_OK)
	{
		printf("sqlite3_close failed:%s __%d__\n", sqlite3_errmsg(db), __LINE__);
		return -1;
	}
	return 3;
}

//查找用户名是否存在
int do_select_user(sqlite3 *db,char *name)
{
	char sql[128] = "select name from user;";
	char **pres = NULL;
	int row,column;
	char *errmsg = NULL;
	if(sqlite3_get_table(db,sql,&pres,&row,&column,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"sqlite3_exec: %s __%d__\n",errmsg,__LINE__);
		return -1;
	}

	for(int i=1;i<(row+1)*column;i++)
	{
		if(strcmp(pres[i],name) == 0)
		{
			fprintf(stderr,"sqlite3_exec: name already existss\n");
			return 1;
		}
	}
	return 0;
}

//实现查询功能函数
int do_insert(sqlite3 *db,char *words,char *mean,char *save_buf)
{
	//获取当前时间戳
	time_t t;
	struct tm *info=NULL;
	char mytime[128] = "";

	t = time(NULL);
	info = localtime(&t);
	sprintf(mytime,"%d-%02d-%02d %02d:%02d:%02d",info->tm_year+1900,info->tm_mon+1,info->tm_mday,info->tm_hour,info->tm_min,info->tm_sec);

	//打开数据库
	if(sqlite3_open("./dict.db",&db) != SQLITE_OK)
	{
		fprintf(stderr,"sqlite3_open: %s __%d__\n",sqlite3_errmsg(db),__LINE__);
		return -1;
	}

	//创建一个表
	char sql[128] = "create table if not exists history (name char,word char,mean char,time char);";
	char *errmsg = NULL;
	char *name = save_buf;

	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"sqlite3_exec: %s __%d__\n",errmsg,__LINE__);
		return -1;
	}

	//插入查询记录
	sprintf(sql,"insert into history values (\"%s\",\"%s\", \"%s\",\"%s\");",name,words, mean,mytime);
	if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
	{
		printf("sqlite3_exec failed:%s __%d__\n", errmsg, __LINE__);
		return -1;
	}
	printf("do_insert success...\n");
}

//查询单词
int do_search(sqlite3 *db,char *buf,char *save_buf)
{
	//打开数据库
	if(sqlite3_open("./dict.db",&db) != SQLITE_OK)
	{
		fprintf(stderr,"sqlite3_open: %s __%d__\n",sqlite3_errmsg(db),__LINE__);
		return -1;
	}

	char sql[128] = "select * from dict;";
	char **pres = NULL;
	int row,column;
	char *errmsg = NULL;
	if(sqlite3_get_table(db,sql,&pres,&row,&column,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"sqlite3_get_table: %s __%d__\n",errmsg,__LINE__);
		return -1;
	}

	char *words = buf+2;

	for(int i=0;i<(row+1)*column;i++)
	{
		if(strcmp(pres[i],words) == 0)
		{
			//若查询成功,则将该单词插入记录
			do_insert(db,words,pres[i+1],save_buf);
			bzero(buf, sizeof(buf));
			sprintf(buf,"\t%s\t\t%s\t",pres[i],pres[i+1]);
			if(sqlite3_close(db) != SQLITE_OK)
			{
				printf("sqlite3_close failed:%s __%d__\n", sqlite3_errmsg(db), __LINE__);
				return -1;
			}
			return 4;
		}
	}

	//关闭数据库,释放对应的内存空间
	if(sqlite3_close(db) != SQLITE_OK)
	{
		printf("sqlite3_close failed:%s __%d__\n", sqlite3_errmsg(db), __LINE__);
		return -1;
	}
	return 5;
}

//查询记录函数
int do_search_res(sqlite3 *db,char *buf,char *save_buf)
{
	//打开数据库
	if(sqlite3_open("./dict.db",&db) != SQLITE_OK)
	{
		fprintf(stderr,"sqlite3_open: %s __%d__\n",sqlite3_errmsg(db),__LINE__);
		return -1;
	}

	char sql[128] = "create table if not exists history (name char,word char,mean char,time char);";
	char *errmsg = NULL;

	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"sqlite3_exec: %s __%d__\n",errmsg,__LINE__);
		return -1;
	}

	char msg[128] = "";
	strcpy(sql,"select * from history;");
	char **pres = NULL;
	int row,column;
	if(sqlite3_get_table(db,sql,&pres,&row,&column,&errmsg) != SQLITE_OK)
	{
		fprintf(stderr,"sqlite3_get_table: %s __%d__\n",errmsg,__LINE__);
		return -1;
	}

	bzero(buf,sizeof(buf));
	for(int i=4;i<(row+1)*column;i++)
	{
		if(i%4==0 && strcmp(save_buf,pres[i]) == 0)
		{
			sprintf(msg,"%s\t%s\t%s\t%s\n",pres[i],pres[i+1],pres[i+2],pres[i+3]);
			strcat(buf,msg);
		}
	}
	if(strlen(buf)!=0)
		*(buf+strlen(buf)-1) = 0;
	//关闭数据库,释放对应的内存空间
	if(sqlite3_close(db) != SQLITE_OK)
	{
		printf("sqlite3_close failed:%s __%d__\n", sqlite3_errmsg(db), __LINE__);
		return -1;
	}
	if(strlen(buf) == 0)
		return 7;
	return 6;
}
//服务器子进程处理客户端信息
int deal_cli_msg(int newfd,struct sockaddr_in cin,sqlite3 *db)
{
	int flag = 0;
	char buf[128] = "";
	char save_buf[128] = "";
	ssize_t res = 0;
	int f_res = -1;
	while(1)
	{
		bzero(buf, sizeof(buf));
		//接收数据
		res = recv(newfd, buf, sizeof(buf), 0);
		if(res < 0)
		{
			ERR_MSG("recv");
			return -1;
		}
		else if(0 == res)
		{
			printf("[%s : %d] client offline\n",inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));
			break;
		}

		//调用功能函数
		if(strcmp(buf,"1") == 0)
			f_res = Register(db,buf); //注册
		else if(strcmp(buf,"2") == 0)
		{
			f_res = Login(db,buf);    //登录
			strcpy(save_buf,buf+2);     //将用户名另存
		}
		else if(strcmp(buf,"3") == 0)
		{
			f_res = do_search(db,buf,save_buf);   //查询单词
		}
		else if(strcmp(buf,"4") == 0)
			f_res = do_search_res(db,buf,save_buf);   //查询记录


		//发送数据
		if(0 == f_res)
		{
			bzero(buf, sizeof(buf));
			strcpy(buf,"[注册成功!]");
		}
		else if(1 == f_res)
		{
			bzero(buf, sizeof(buf));
			strcpy(buf,"[对不起,注册失败,该用户名已存在!]");
		}
		else if(2 == f_res)
		{
			bzero(buf, sizeof(buf));
			strcpy(buf,"[登录成功!]");
		}
		else if(3 == f_res)
		{
			bzero(buf, sizeof(buf));
			strcpy(buf,"[对不起,登录失败,该用户名/密码不存在!]");
		}
		else if(5 == f_res)
		{
			bzero(buf, sizeof(buf));
			strcpy(buf,"[对不起,无法查找找到该单词!]");
		}
		else if(7 == f_res)
		{
			bzero(buf, sizeof(buf));
			strcpy(buf,"[对不起,该用户没有历史记录!]");
		}

		if(send(newfd, buf, sizeof(buf), 0) < 0)
		{
			ERR_MSG("send");
			return -1;
		}
	}
	close(newfd);
	return 0;
}

服务器(Ser.c):

#include "head.h"
int main(int argc, const char *argv[])
{
	sqlite3 *db = NULL;
 
    if(signal(17, handler) == SIG_ERR)
    {
        ERR_MSG("signal");
        return -1;
    }
	//导入词典	
	put_dict(db);
	//创建流式套接字
	int sfd = socket(AF_INET,SOCK_STREAM,0);
	if(sfd < 0)
	{
		ERR_MSG("socket");
		return -1;
	}
 
    //设置允许端口号复用
    int reuse = 1;
    if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)  
    {                                                                          
        perror("setsockopt");
        return -1;
    }
 
	//绑定服务器IP和端口号
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);
	sin.sin_addr.s_addr = inet_addr(IP);
	if(bind(sfd,(struct sockaddr *)&sin,sizeof(sin)) < 0)
	{
		ERR_MSG("bind");
		return -1;
	}
 
	//将套接字设置为被动监听状态
	if(listen(sfd,10) < 0)
	{
		ERR_MSG("listen");
		return -1;
	}
	
	int newfd = -1;
	struct sockaddr_in cin;
	socklen_t addrlen = sizeof(cin);
 
	//从已完成连接的队列中获取一个客户端信息,生成一个新的文件描述符
	while(1)
	{
		newfd = accept(sfd,(struct sockaddr *)&cin,&addrlen);
		if(newfd < 0)
		{
			ERR_MSG("accept");
			return -1;
		}
		printf("[%s : %d] connect success...\n",inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));
		if(0 == fork())
		{
			close(sfd);
			deal_cli_msg(newfd,cin,db);
			exit(0);
		}
		close(newfd);
	}
	close(sfd);
	return 0;
}

客户端(Cli.c):

#include "head.h"

int main(int argc, const char *argv[])
{
	sqlite3 *db =NULL;

	//创建流式套接字
	int cfd = socket(AF_INET, SOCK_STREAM, 0);
	if(cfd < 0)
	{
		ERR_MSG("socket");
		return -1;
	}
	printf("cfd = %d\n", cfd);

	//绑定客户端的的IP和端口--->非必须绑定
	//若不绑定,则操作系统会给客户端绑定上客户端所在的主机IP,以及随机端口(49152~65535)


	//填充服务器的地址信息结构体,真实的地址信息结构体根据地址族指定
	//AF_INET: man 7 ip 
	//要连接哪个服务器,就填对应服务器的IP和端口
	struct sockaddr_in sin;
	sin.sin_family      = AF_INET;      //必须填AF_INET
	sin.sin_port        = htons(PORT);  //端口号: 填服务器绑定端口号
	sin.sin_addr.s_addr = inet_addr(IP); //IP地址:服务器绑定的IP地址

	//连接服务器
	if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
	{
		ERR_MSG("connect");
		return -1;
	}
	printf("connect success\n");

	ssize_t res = 0;
	char buf[128] = "";
	char buf1[128] ="";
	char save_buf[128] ="";
	char choose = 0;
	while(1)
	{
		system("clear");
		printf("-----------------------\n");
		printf("---------1.注册--------\n");
		printf("---------2.登录--------\n");
		printf("---------3.退出--------\n");
		printf("-----------------------\n");
		printf("请输入您需要执行的操作>>>");
		choose = getchar();
		while(getchar() != 10);
		switch(choose)
		{
		case '1':
			//注册函数
			do_register_cli(buf);
			break;
		case '2':
			//登录函数
			do_login(buf);
			break;
		case '3':
			//退出函数
			goto END;
		default:
			printf("对不起,您的输入有误,请重新输入\n");
		}

		//发送数据
		if(send(cfd,buf,sizeof(buf),0) < 0)
		{
			perror("send");
			return -1;
		}

		//接受数据
		bzero(buf,sizeof(buf));
		res = recv(cfd,buf,sizeof(buf),0);
		if(res < 0)
		{
			perror("recv");
			return -1;
		}
		else if(0 == res)
		{
			printf("[%s : %d] server offline\n",IP,PORT);
			break;
		}
		printf("%s\n",buf);


		strcpy(save_buf,buf);
		while(strcmp(save_buf,"[登录成功!]") == 0)
		{
			system("clear");
			printf("--------------------------\n");
			printf("-------1.查找单词---------\n");
			printf("-------2.查找历史记录-----\n");
			printf("-------3.退出登录---------\n");
			printf("--------------------------\n");
			printf("请输入您要执行的操作>>>");
			choose = getchar();
			while(getchar() != 10);

			//		bzero(buf,sizeof(buf));
			//		fgets(buf,sizeof(buf),stdin);
			//		buf[strlen(buf)-1] = 0;

			char words[20] = "";

			switch(choose)
			{
			case '1':
				{
					while(1)
					{
						bzero(buf,sizeof(buf));
						printf("请输入您要查找的单词(输入 \"#\" 结束)>>>");
						scanf("%s",words);
						getchar();
						if(strcmp(words,"#") == 0)
							break;
						sprintf(buf,"%s%c%s%c","3",0,words,0);

						//发送数据
						if(send(cfd,buf,sizeof(buf),0) < 0)
						{
							perror("send");
							return -1;
						}
						//接收查询单词结果
						bzero(buf,sizeof(buf));
						res = recv(cfd,buf,sizeof(buf),0);
						if(res < 0)
						{
							perror("recv");
							return -1;
						}
						else if(0 == res)
						{
							printf("[%s : %d] server offline\n",IP,PORT);
							//	break;
							goto END;
						}
						printf("%s\n",buf);
					}
				}
				break;
			case '2':
				//登录函数
				{
					sprintf(buf,"%s%c","4",0);

					//发送数据
					if(send(cfd,buf,sizeof(buf),0) < 0)
					{
						perror("send");
						return -1;
					}
					//接受查询单词结果
					bzero(buf,sizeof(buf));
					res = recv(cfd,buf,sizeof(buf),0);
					if(res < 0)
					{
						perror("recv");
						return -1;
					}
					else if(0 == res)
					{
						printf("[%s : %d] server offline\n",IP,PORT);
						goto END;
						//	break;
					}
					printf("%s\n",buf);
				}
				break;
			case '3':
				goto END1;
			default:
				printf("对不起,您的输入有误,请重新输入\n");
			}

			printf("输入任意字符清屏>>>");
			while(getchar() != 10);

		}
END1:
		printf("输入任意字符清屏>>>");
		while(getchar() != 10);
	}
END:

	//关闭所有文件描述符
	close(cfd);

	return 0;
}

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

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

相关文章

三、mycat分库分表

第五章 分库分表 一个数据库由很多表的构成&#xff0c;每个表对应着不同的业务&#xff0c;垂直切分是指按照业 务将表进行分类&#xff0c;分布到不同 的数据库上面&#xff0c;这样也就将数据或者说压力分担到不同 的库上面&#xff0c;如下图&#xff1a; 系统被切分成了&…

three.js(四):react + three.js

绘制多个立方体 1.搭建reactts 项目 npx create-react-app basics-demo --template typescriptreactts 的用法可参考此链接&#xff1a; https://react-typescript-cheatsheet.netlify.app/docs/basic/setup 2.安装three依赖 npm install three types/three --save3.安装路…

200 套基于Java开发的Java毕业设计实战项目(含源码+说明文档)

文章目录 简介前言第一部分第二部分部分截图源码咨询 简介 博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 前言 对于java方向的毕业设计题目选题&#xf…

Weblogic漏洞(四)之 CVE-2018-2894 任意文件上传漏洞

CVE-2018-2894 任意文件上传漏洞 漏洞影响 Weblogic受影响的版本&#xff1a; 10.3.6.012.1.3.012.2.1.212.2.1.3 漏洞环境 此次我们使用的是vnlhub靶场搭建的环境&#xff0c;是vnlhub中的Weblogic漏洞中的CVE-2018-2894靶场&#xff0c;我们 cd 到 CVE-2018-2894&#x…

R3LIVE源码解析(6) — R3LIVE流程详解

目录 1 R3LIVE框架简介 2 R3LIVE的launch文件 3 R3LIVE的r3live_config文件 4 R3LIVE从哪开始阅读 1 R3LIVE框架简介 R3LIVE是香港大学Mars实验室提出的一种融合imu、相机、激光的SLAM方法&#xff0c;R3LIVE由两个子系统组成&#xff0c;一个激光惯性里程计&#xff08;L…

【无标题】8.31在华清

可以登录但是不能跳转

怎么用postman连接websocket

点击右侧栏的Collections&#xff0c;然后点击旁边的New&#xff0c;然后点击其中的WebSocket Request,然后输入Url&#xff0c;点击Connection&#xff0c;这里需要注意的是Url不能加上http://&#xff0c;因为这个不是http协议。

23062网络编程day5

根据select TCP服务器流程图编写服务器 #include <myhead.h> #define ERR_MSG(msg) do{\fprintf(stderr,"__%d__:",__LINE__);\perror(msg);\ }while(0)#define PORT 8888 #define IP "192.168.114.104"int keyboard_events(void); int cliConnect_…

美国纽约10日游

一、前言 我有两周断更了&#xff0c;原因是去纽约只顾着玩&#xff0c;没时间写&#xff0c;今天有时间正好和大家分享一下去纽约的攻略 二、以下是一个10天去美国纽约旅游的攻略&#xff0c;十万以内&#xff0c;包括机票、酒店、交通、餐饮和景点门票等费用&#xff1a; 第…

Leetcode ->206 反转链表

题目 算法思路及代码实现 #include <iostream> using namespace std;struct ListNode {int val; //当前节点的值ListNode *next;

目标检测笔记(十二):如何通过界面化操作YOLOv5完成数据集的自动标注

文章目录 一、意义二、修改源码获取三、自动标注前期准备四、开始自动标注五、可视化标注效果六、XML转换TXT 一、意义 通过界面化操作YOLOv5完成数据集的自动标注的意义在于简化数据标注的流程&#xff0c;提高标注的效率和准确性。 传统的数据集标注通常需要手动绘制边界框…

通信笔记:RSRP、RSRQ、RSNNR

0 基础概念&#xff1a;RE、RS和RB RE (Resource Element)&#xff1a;资源元素是 LTE 和 5G 网络中的最小物理资源单位。一个资源元素对应于一个子载波的一个符号周期。 RS (Reference Signal)&#xff1a;参考信号是在 LTE 和 5G 网络中用于多种目的的特定类型的信号。它们可…

PyCharm切换虚拟环境

PyCharm切换虚拟环境 为了满足不同任务需要不同版本的包&#xff0c;可以在Anaconda或者Miniconda创建多个虚拟环境文件夹&#xff0c;并在PyCharm下切换虚拟环境。 解决方案 1、打开Ananconda Prompt 2、创建自己的虚拟环境 格式&#xff1a;conda create -n 虚拟环境名字…

SSH远程连接macOS服务器:通过cpolar内网穿透技术实现远程访问的设置方法

文章目录 前言1. macOS打开远程登录2. 局域网内测试ssh远程3. 公网ssh远程连接macOS3.1 macOS安装配置cpolar3.2 获取ssh隧道公网地址3.3 测试公网ssh远程连接macOS 4. 配置公网固定TCP地址4.1 保留一个固定TCP端口地址4.2 配置固定TCP端口地址 5. 使用固定TCP端口地址ssh远程 …

《华为认证》二层EVPN的配置

步骤1&#xff1a;配置PE和P设备的IGP以及mpls、mpls ldp&#xff08;略&#xff09; 步骤2&#xff1a;配置evpn实例&#xff0c;并且绑定到BD中&#xff0c;配置evpn的源ip地址 PE1: evpn vpn-instance 1 bd-mode //指定创建BD模式EVPN实例 route-distinguisher 100:1 vpn-…

【Leetcode】130.被围绕的区域

一、题目 1、题目描述 给你一个 m x n 的矩阵 board ,由若干字符 X 和 O ,找到所有被 X 围绕的区域,并将这些区域里所有的 O 用 X 填充。 示例1: 输入:board = [[“X”,“X”,“X”,“X”],[“X”,“O”,“O”,“X”],[“X”,“X”,“O”,“X”],[“X”,“O”,“X”,“…

操作符算数转换题

目录 1.交换两个变量&#xff08;不创建临时变量&#xff09; 2.统计二进制中1的个数 3.打印整数二进制的奇数位和偶数位 4.求两个数二进制中不同位的个数 5.【一维数组】有序序列合并 6.获得月份天数 7.变种水仙花数 8.选择题总结tips 这篇博文主要分享操作符&算…

[蓝桥复盘] 算法赛内测赛2 20230831

[蓝桥复盘] 算法赛内测赛2 20230831 总结新一与基德的身高大战1. 题目描述2. 思路分析3. 代码实现 肖恩的投球游戏加强版1. 题目描述2. 思路分析3. 代码实现 体育健将1. 题目描述2. 思路分析3. 代码实现 小桥的奇异旋律1. 题目描述2. 思路分析3. 代码实现 区间or划分1. 题目描…

刷新你对Redis持久化的认知

认识持久化 redis是一个内存数据库&#xff0c;数据存储到内存中。而内存的数据是不持久的&#xff0c;要想做到持久化&#xff0c;就需要让redis把数据存储到硬盘上。因此redis既要在内存上存储一份数据&#xff0c;还要在硬盘上存储一份数据。这样这两份数据在理论上是完全相…

掌握Spring框架核心组件:深入探讨IOC、AOP、MVC及注解方式面试指南【经验分享】

目录 引言 一、Spring IOC篇 1.什么是Spring 2.核心概念 3.核心架构 4.什么是控制反转&#xff08;IOC&#xff09; 5.依赖注入&#xff08;DI&#xff09; 二、Spring AOP篇 1.什么是AOP 2.Spring AOP代理机制 3.核心概念 4.通知分类 三、Spring MVC篇 1.什么…