对于思维不活跃的我学习编程

思维不灵活的我如何学习编程

  1. 对于我个人而言,面对不熟悉的代码,如何去学习,在我的学习之路上面对的一堆堆的看不懂的东西,英语也不是特别的好,对于我而言,就是通过去对代码的不断去注释,去理解它的用法,去了解这个函数/方法,比如它的返回值是什么,传入的参数是什么类型,等等,在代码处写下自己的理解,(自己怎么想的就怎么写可能效果要好的多),通过对一个个项目的不断注释去提高自己,抄写别人的代码不可耻,去把别人的代码,写作的思路学习到就很好。
  2. 下面是我通过网络词典的注释理解到的写作思路
头文件

#ifndef com_h
#define com_h

struct msg{
	int opt;
	//选择 1.注册 2,登录 3.查询 4修改密码 5.查询历史记录
	char use_name[16];
	//使用者账号
	char use_password[16];
	//使用者密码
	
	int login_res;
	//服务器回应值	0-成功  -1-失败	
	char resbuf[256];
	//回应内容
	int look_res;
	//单词查询返回	0-成功	-1-失败
	int update_res;
	//修改密码返回值 0-成功  -1-失败
	char find_word[16];
	//查询单词
	char word_exp[1024];
	//单词及注释/解释
	int wordlen;
	//单词长度
	char hisbuf[64];
	//历史记录
};
#endif

```c
服务器
#include <stdio.h>
#include <sys/types.h>          
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "common.h"
#include <unistd.h>
#include <pthread.h>
#include <sqlite3.h>
#include <stdlib.h>
#include <time.h>

int ser_fd,ser_fd_new;		//服务器的主线程和新线程的名字
struct msg ser_msg;			//服务器用于接收和发送的空间--使用全局变量,可以避免传参而导致的数据丢失
int ret;					//用于作为发送,接收等的返回值
sqlite3 *db;				//数据库的地址,通过db去操作数据库
	
struct my_socket_new{
		int socket_new;		//产生新的连接去连接新的线程
		pthread_t tid;		//线程的tid
};
//注册操作
int do_sign(int socket_new)
{
	char **ptable = NULL;		//表的地址
	int nrow,ncol;				//行与列
	char sqlbuf[128];			//存放sql语句的地方
	memset(sqlbuf,0,sizeof(sqlbuf));		//存放前先清空
	//截胡printf,将SQL语句放置在sqlbuf中
	snprintf(sqlbuf,sizeof(sqlbuf),\
	"select *from user where name=\'%s\'",ser_msg.use_name);
	ret = sqlite3_open("./dic.db",&db);
		if(ret){
			printf("open err:%s\n",sqlite3_errmsg(db));
			return -1;
		}		//对数据库进行查询操作,是否被存在
	ret = sqlite3_get_table(db,sqlbuf,&ptable,&nrow,&ncol,NULL);
		if(ret){
			printf("select name err:%s\n",sqlite3_errmsg(db));
			return -1;
		}			
		if(nrow){
			//行不等于0,查询到相关的信息,说明该用户已经存在
			strcpy(ser_msg.resbuf,"this`s user already be used !");
		}else{
			//如果行的值等于0,说明没有查询到信息,可以插入/注册
			strcpy(ser_msg.resbuf,"use name sign success !");
			memset(sqlbuf,0,sizeof(sqlbuf));
			snprintf(sqlbuf,sizeof(sqlbuf),\
				"insert into user (name,password) values (\'%s\',\'%s\')",\
				ser_msg.use_name,ser_msg.use_password);
				//没有记录,插入客服端的值到数据库中
			ret=sqlite3_get_table(db,sqlbuf,&ptable,NULL,NULL,NULL);
				if(ret){
					printf("intsert into err:%s\n",sqlite3_errmsg(db));
					return -1;
				}
		}
		//操作结束,操作结果发给客服端
	ret = send(socket_new,&ser_msg, sizeof(ser_msg),0);
		if(ret < 0){
			perror("insert into send err");
			return -1;
		}
	ret = sqlite3_close(db);
		if(ret){
			printf("close err:%s\n",sqlite3_errmsg(db));
			return -1;
		}	
	return 0;
}
//登录操作
int do_login(int socket_new)
{
	char **ptable = NULL;		//表的地址
	int nrow,ncol;				//行与列
	char sqlbuf[128];			//存放sql语句的地方
	memset(sqlbuf,0,sizeof(sqlbuf));		//存放前先清空
	//截胡printf,将SQL语句放置在sqlbuf中
	snprintf(sqlbuf,sizeof(sqlbuf),\
	"select *from user where name=\'%s\' and password=\'%s\'",\
	ser_msg.use_name,ser_msg.use_password);
	ret = sqlite3_open("./dic.db",&db);
		if(ret){
			printf("open err:%s\n",sqlite3_errmsg(db));
			return -1;
		}		//对数据库进行查询操作,是否被存在
	ret = sqlite3_get_table(db,sqlbuf,&ptable,&nrow,&ncol,NULL);
		if(ret){
			printf("select name err:%s\n",sqlite3_errmsg(db));
			return -1;
		}				//没有查询到记录,登录失败
		if(nrow == 0){
			ser_msg.login_res = -1;
			strcpy(ser_msg.resbuf,"login falied !");
		}else{			//反之,查询到记录,登录成功
			ser_msg.login_res = 0;
			strcpy(ser_msg.resbuf,"login success !");
		}				//数据处理完成,发送结果值客服端
	ret=send(socket_new,&ser_msg, sizeof(ser_msg),0);
		if(ret<0){
			perror("send failed");
			return -1;
		}
	ret = sqlite3_close(db);
		if(ret){
			printf("close err:%s\n",sqlite3_errmsg(db));
			return -1;
		}
	return 0;
}
//查询单词
int look_word(int socket_new)
{
	char cli_word[16];		//用来暂时存放来自客服端的单词
	char ser_word[1024];	//用来存放获取到关于单词一整行的内容
	FILE *fp;
	fp=fopen("./dict.txt","r");
		if(fp==NULL){
			perror("fopen");
			return -1;
		}
	while(1)
	{
		//获取文本中每一行
		if(fgets(ser_word,sizeof(ser_word),fp) !=NULL)
		{	
			for (int j=0;ser_word[j] !=' ';j++){
				cli_word[j]=ser_word[j];		
				//将单词放置在发给客服端的数组中
			}
			//判断单词与客服端发送的是否一致
			if(strcmp(cli_word,ser_msg.find_word)==0)	
			{	//将查询到的内容发送给客服端
				strcpy(ser_msg.word_exp,ser_word);	
				//每次查询完之后都要清空,以便于循环查询
				memset(cli_word,0,sizeof(cli_word));
				memset(ser_word,0,sizeof(ser_word));
				ser_msg.look_res = 0;	//发送查询结果到客服端
			}else{	//由于对比的时候有赋值操作,不一致时也需要清空容器
				memset(cli_word,0,sizeof(cli_word));
				memset(ser_word,0,sizeof(ser_word));
			}
		}	//查询到空的行,说明关于该单词的内容不存在
		else{
			ser_msg.look_res = -1;
			stpcpy(ser_msg.resbuf,"sorry no find anything !");
		}	//将查询结果发送给客服端
		ret=send(socket_new,&ser_msg, sizeof(ser_msg),0);
			if(ret<0){
			perror("send failed");
			return -1;
			}
		char **ptable = NULL;		//表的地址
		int nrow,ncol;				//行与列
		fclose(fp);
		//时间获取
		time_t look_time;		
		char look_time_buf[32];		//存放时间的容器
		struct tm *look_tm;		
		time(&look_time);		
		look_tm = localtime(&look_time);	//获取当前本地时间
		snprintf(look_time_buf,sizeof(look_time_buf),"%d-%d-%d %d-%d-%d",look_tm->tm_year+1900,look_tm->tm_mon+1,\
				look_tm->tm_mday,look_tm->tm_hour,look_tm->tm_min,look_tm->tm_sec);
		//暂时将时间存放在look_time_buf中
		char sql_look_record[128];		//存放浏览记录的sq的容器
		memset(sql_look_record,0,sizeof(sql_look_record));
		snprintf(sql_look_record,sizeof(sql_look_record),\
			"intsert into history (name,day,word) values(\'%s\',\'%s\',\'%s\',)",\
			ser_msg.use_name,look_time_buf,ser_msg.find_word);
		ret=sqlite3_open("./dic.db",&db);			//将数据存放在数据的表中
			if(ret){
				printf("look open err:%s\n",sqlite3_errmsg(db));
				return -1;
			}
		ret = sqlite3_get_table(db,sql_look_record,&ptable,&nrow,&ncol,NULL);
			if(ret){
				printf("sqlite3_get_table in look err:%s\n",sqlite3_errmsg(db));
				return -1;
			}
		ret = sqlite3_close(db);
			if(ret){
				printf("close err:%s\n",sqlite3_errmsg(db));
				return -1;
			}
	}
	return 0;
}
//修改密码
int update_password(int socket_new)
{
	char **ptable = NULL;		//表的地址
	char sqlbuf[128];
	int nrow,ncol;				//行与列
	memset(sqlbuf,0,sizeof(sqlbuf));
	snprintf(sqlbuf,sizeof(sqlbuf),		//根据客服端的用户名去寻找对应的那一行
	"select *from user where name=\'%s\'",ser_msg.use_name);
	ret = sqlite3_open("./dic.db",&db);
		if(ret){
			printf("update open err:%s\n",sqlite3_errmsg(db));
			return -1;
		}
	ret = sqlite3_get_table(db,sqlbuf,&ptable,&nrow,&ncol,NULL);
		if(ret){
			printf("sqlite3_get_table in update err:%s\n",sqlite3_errmsg(db));
			return -1;
		}
	if(nrow == 0){			//如果行等于0,则说明没有注册过
		ser_msg.update_res = -1;
		stpcpy(ser_msg.resbuf,"your name is unreal !!");
	}else{					//反之,则是注册过
		ser_msg.update_res = 0;
		memset(sqlbuf,0,sizeof(sqlbuf));
		//更新数据,将密码替换成客服端传来的密码
		snprintf(sqlbuf,sizeof(sqlbuf),\
		"update user set passwd=\'%s\' where name=\'%s\'",\
		ser_msg.use_password,ser_msg.use_name);
		ret = sqlite3_get_table(db,sqlbuf,&ptable,&nrow,&ncol,NULL);
		if(ret){
			printf("update_sqlite3_get_table err:%s\n",sqlite3_errmsg(db));
			return -1;
		}
	}
	ret = sqlite3_close(db);
		if(ret){
			printf("close in update password err:%s\n",sqlite3_errmsg(db));
			return -1;
		}				//更新数据成功,将结果返回至客服端
	strcpy(ser_msg.resbuf,"update password success");
	ret=send(socket_new,&ser_msg, sizeof(ser_msg),0);
		if(ret<0){
			perror("send failed");
		return -1;
		}
	return 0;
}
//查看历史记录
int look_history(int socket_new)
{
	char hissqlbuf[128];		//装放查询历史记录的sql语句
	int nrow,ncol;
	char **ptable=NULL;
	memset(hissqlbuf,0,sizeof(hissqlbuf));	//遍历历史记录表
	snprintf(hissqlbuf,sizeof(hissqlbuf),"select * from history");
	ret=sqlite3_open("./dic.db",&db);
		if(ret){
			printf("open err:%s\n",sqlite3_errmsg(db));
			return -1;
		}
	ret = sqlite3_get_table(db,hissqlbuf,&ptable,&nrow,&ncol,NULL);
		if(ret){
			printf("sqlite3_get_table err:%s\n",sqlite3_errmsg(db));
			return -1;
		}
	char hisbuf1[128];		//放置查询到的历史记录内容
	if(nrow>=5)				
	{
		for(int i=(nrow-5)*ncol;i<(nrow+1)*ncol;i++)
		{
			snprintf(hisbuf1,sizeof(hisbuf)," %s ",ptable[i]);
			strcat(ser_msg.hisbuf,hisbuf1);
			if((i+1)%ncol==0){
				printf("\n");
				strcat(ser_msg.hisbuf,"\n");
			}
		}
	}
	else
	{
		for(int i=0;i<(nrow+1)*ncol;i++)
		{
			snprintf(hisbuf1,sizeof(hisbuf)," %s ",ptable[i]);
			strcat(ser_msg.hisbuf,hisbuf1);
			if((i+1)%ncol==0){
				printf("\n");
				strcat(ser_msg.hisbuf,"\n");
			}
		}
	}
	ret=send(socket_new,&ser_msg, sizeof(ser_msg),0);
		if(ret<0){
			perror("send failed");
			return -1;
		}
	ret = sqlite3_close(db);
		if(ret){
			printf("close err:%s\n",sqlite3_errmsg(db));
			return -1;
		}
	return  0;
}
//子线程操作/运行函数---对来自客服端的数据进行处理
void *cli_thread_new(void *args)
{
	while(1)
	{	
		struct my_socket_new *pnew = args;
		ret = recv(ser_fd_new,&ser_msg,sizeof(ser_msg),0);
		if(ret < 0){
			perror("recv falied");
			return NULL;
		}else if(ret == 0){		//防止注册完成后客服端没有发生信息导致服务器关闭
			printf("wait ....\n");
			return NULL;
		}
			switch(ser_msg.opt)
			{
				case 1:		//注册操作
					do_sign(pnew->socket_new);
					break;
				case 2:		//登录操作
					do_login(pnew->socket_new);
					break;
				case 3:		//单词查询
					look_word(pnew->socket_new);
					break;
				case 4:		//修改密码
					update_password(pnew->socket_new);
					break;
				case 5:		//查看历史记录
					look_history(pnew->socket_new);
					break;
				default:
					break;
			}
	}
	return NULL;
}

int main()
{
	//创建一个套接字/连接
	ser_fd=socket(AF_INET,SOCK_STREAM,0);
	if(ser_fd<0){
		perror("socket create error");
		return -1;
	}
	struct sockaddr_in serv_addr;
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(8888);
	serv_addr.sin_addr.s_addr = INADDR_ANY;
//	serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
	//绑定
	ret=bind(ser_fd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
		if(ret<0){
			perror("bind error");
			return -1;
		}
	//监听
	ret=listen(ser_fd,5);
		if(ret<0){
			perror("listen error");
			return -1;
		}
	struct sockaddr_in cli_addr;
	socklen_t clilen=sizeof(cli_addr);
loop:
	//新连接
	ser_fd_new=accept(ser_fd,(struct sockaddr *)&cli_addr,&clilen);
		if(ser_fd_new<0){
			perror("accept error");
			return -1;
		}
	printf("serv accept client ip=%s port=%d\n",\
	inet_ntoa (cli_addr.sin_addr ), ntohs(cli_addr.sin_port));
	//开新的线程
	struct my_socket_new *pnew=malloc(sizeof(struct my_socket_new));
	pnew->socket_new=ser_fd_new;
	ret=pthread_create(&pnew->tid,NULL,cli_thread_new,pnew);
		if(ret!=0){
			perror("pthread_create");
			return -1;
		}
goto loop;
	close(ser_fd_new);
	return 0;
}
客服端
#include <stdio.h>
#include <sys/types.h>          
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "common.h"
#include <unistd.h>
#include <pthread.h>
#include <sqlite3.h>
#include <stdlib.h>
#include <time.h>

int cli_fd;				//全局套接字变量,可以避免传参出现错误
struct msg climsg;		//客服端接收和发送空间
int ret;				//用于作为发送,接收等的返回值

void mainshow()
{
	printf("~~~~~~~~~~\n");
	printf("网络小词典\n");
	printf("1:注册账号\n");
	printf("2:登录\n");
	printf("3:退出\n");
	printf("~~~~~~~~~~\n");
}
void sonshow()
{
	printf("~~~~~~~~~~\n");
	printf("操作选择\n");
	printf("1:查询单词\n");
	printf("2:查看历史记录\n");
	printf("3:修改密码\n");
	printf("4:返回主界面\n");
	printf("~~~~~~~~~~\n");
}
//注册账号
int do_sign()
{
	//发送内容
	char sign_name[16];
	char sign_password[16];
	memset(&climsg,0,sizeof(climsg));
	printf("please input your sign name:");
	scanf("%s",sign_name);
	printf("please input your sign passwd:");
	scanf("%s",sign_password);
	strcpy(climsg.use_name,sign_name);
	strcpy(climsg.use_password,sign_password);
	climsg.opt=1;
	//发送至服务器
	ret=send(cli_fd,&climsg,sizeof(climsg),0);
	if(ret<0){
		perror("sign msg send error");
		return -1;
	}
	//接收服务器的返回内容
	memset(&climsg,0,sizeof(climsg));
	ret=recv(cli_fd,&climsg,sizeof(climsg),0);
	if(ret<0){
		perror("sign msg recv error");
		return -1;
	}else if(ret==0){
		printf("sign find server is close\n");
		return -1;
		close(cli_fd);
	}
	//打印返回内容
	printf("%s\n",climsg.resbuf);
	close(cli_fd);
	return 0;
}
//登录操作
int do_login()
{
	//发送内容
	char login_name[16];
	char login_password[16];
	memset(&climsg,0,sizeof(climsg));
	printf("please input your sign name:");
	scanf("%s",login_name);
	printf("please input your sign passwd:");
	scanf("%s",login_password);
	strcpy(climsg.use_name,login_name);
	strcpy(climsg.use_password,login_password);
	climsg.opt=2;
	//发送至服务器
	ret=send(cli_fd,&climsg,sizeof(climsg),0);
	if(ret<0){
		perror("login msg send error");
		return -1;
	}
	//接收服务器的返回内容
	memset(&climsg,0,sizeof(climsg));
	ret=recv(cli_fd,&climsg,sizeof(climsg),0);
	if(ret<0){
		perror("login recv error");
		return -1;
	}else if(ret==0){
		printf("login find server is close\n");
		return -1;
		close(cli_fd);
	}
	//打印返回内容
	printf("%s\n",climsg.resbuf);
	close(cli_fd);
	return 0;
}
//查询单词
int look_word()
{
	char myword[16];			//放置查询的单词
	printf("please input you want to look thing:");
	scanf("%s",myword);
	climsg.wordlen=strlen(myword);		//单词的长度赋值
	strcpy(climsg.find_word,myword);	//单词赋值准备发送
	climsg.opt = 3;						//操作类型发送至服务器
	ret=send(cli_fd,&climsg,sizeof(climsg),0);		//send
		if(ret<0){
			perror("look word send error:");
			return -1;
		}
	ret=recv(cli_fd,&climsg,sizeof(climsg),0);		//recv
		if(ret<0){
			perror("look word recv error:");
			return -1;
		}else if(ret==0){
			printf("looking word server is close\n");
			return -1;
		}
	if(climsg.look_res ==0){			//服务器查询到单词,返回单词的注释
		printf("%s",climsg.word_exp);	
	}else if(climsg.look_res ==-1){		//服务器没有找到
		printf("%s",climsg.resbuf);
	}
	return 0;
}
//查询历史记录
int history()
{
	climsg.opt=5;
	ret=send(cli_fd,&climsg,sizeof(climsg),0);		//send
		if(ret<0){
			perror("look history send error:");
			return -1;
		}
	ret=recv(cli_fd,&climsg,sizeof(climsg),0);		//recv
		if(ret<0){
			perror("look history recv error:");
			return -1;
		}else if(ret==0){
			printf("looking history server is close\n");
			return -1;
		}
	printf("%s\n",climsg.hisbuf);
	return 0;
}
//修改密码
int update_password()
{
	char newpassword[32];			//存放新密码的容器
	char updatename[16];			//存放寻找修改密码是用到用户名
	printf("please input your user name :");
	scanf("%s",updatename);
	printf("please input your new passwd:");
	scanf("%s",newpassword);
	memset(&climsg,0,sizeof(climsg));
	stpcpy(climsg.use_password,newpassword);
	stpcpy(climsg.use_name,updatename);	//发送内容赋值
	climsg.opt=4;
	ret=send(cli_fd,&climsg,sizeof(climsg),0);		//send
		if(ret<0){
			perror("update password send error:");
			return -1;
		}
	ret=recv(cli_fd,&climsg,sizeof(climsg),0);		//recv
		if(ret<0){
			perror("update passwordrecv error:");
			return -1;
		}else if(ret==0){
			printf("update password server is close\n");
			return -1;
		}
	printf("%s\n",climsg.resbuf);
	return 0;
}
int main()
{
	//创建连接
	cli_fd=socket(AF_INET,SOCK_STREAM,0);
	if(cli_fd<0){
		perror("socket create error");
		return -1;
	}
	struct sockaddr_in srecv_addr;		//服务器地址
	srecv_addr.sin_family = AF_INET;
	srecv_addr.sin_port = htons(8888);
    srecv_addr.sin_addr.s_addr = inet_addr("192.168.24.130");
//	srecv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
	//连接服务器
	ret=connect(cli_fd,(struct sockaddr *)&srecv_addr,sizeof(srecv_addr));
	if(ret<0){
		perror("connect error:");
		return -1;
	}
login_and_sign:
	while(1)
	{
		int opt;
		mainshow();
		printf("input options:");
		scanf("%d",&opt);
		switch(opt)
		{
			case 1:
				do_sign();
				break;
			case 2:
				do_login();
				switch(climsg.login_res)
				{
					case -1:
					goto login_and_sign;
					case 0:
					printf("login success !!\n");
				look:
					while(1)
					{ 
						int son; 
						sonshow();
						printf("input options:");
						scanf("%d",&son);
						switch(son)
						{
							case 1:
								look_word();
								break;
							case 2:
								history();
								break;
							case 3:
								update_password();
								break;
							case 4:
								goto login_and_sign;
							default:
								printf("your what want going ?\n");
								goto look;
						}
						
					}
				}
				break;
			case 3:
				close(cli_fd);
				break;
			default:
				printf("your what want going ?\n");
goto login_and_sign;
		}
	}
	close(cli_fd);
	return 0;
}

3.可能有部分理解可能有问题,自己的理解能力有限,希望大家可以多多指点,互相学习。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

努力做最好的

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

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

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

打赏作者

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

抵扣说明:

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

余额充值