C语言:简单的Linux版登录系统

引言

很长时间没有更新博客啦,这段时间也比较堕落,希望大家引以为戒…
这次给大家带来一个简单的Linux版登录系统,因为要写课设所以我先写了这个,把它放上来分享给各位。

题外话

一、因为代码里面用了Linux shell的一些指令所以Windows系统下面无法正常运行。并且gcc编译器没有conio.h这个库(因为它不是标准库),所以我用了网上找到的一个自定义函数来代替getch(),还有就是文件名的问题,Linux下严格上来说没有扩展名这一说但是Windows有。
二、s_gets()是一个比较好用的输入函数,它既安全又可以不影响下次输入,并且不会想fgets()那样添加换行符。(来自c primer plus第六版)。
三、总之就是,如果大家想在Windows下运行,修改system()中的语句(用Windows对应指令代替)并把getch()删掉就可以了,快去试试吧~

实现功能

注册、登录、找回密码、密码的加密与解密、密码的隐式输入(并可回删)

代码


#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
#define SIZE 50
//为了安全的输入(防止暴力输入)
char get_choice();	
long get_tele();
char get_first();
char getch();
char * s_gets(char * st, int n);
void secret_pwd(char * pwd);
//具体功能实现函数
void create_user_file();
void register_user();
void login();
void find_pwd();
//加密解密函数
void encipher(char * original);
void decipher(char * cipher);
//菜单函数
void show_line(const char * line);
void user_menu();

typedef struct user		//用户信息主体
{
	char id[SIZE];		//账号
	char pwd[SIZE];		//密码
	long tele;			//电话号码
}user;

int main()
{
	user_menu();
	puts("请按任意键继续...");
	getch();	//模拟任意键继续
	puts("欢迎下次使用!");
	return 0;
}
//保证文件users的存在,该文件存在时也不清空其中的数据
void create_user_file()
{
	FILE * fp;

	if ((fp = fopen("users", "r")) == NULL)	
	{
		if ((fp = fopen("users", "w+")) == NULL)
		{
			fprintf(stderr, "无法打开用户信息!\n");
			system("sleep 3s");
			return;
		}
	}
	fclose(fp);

	return;
}
//显示主界面并获取用户键入的信息
char get_choice(void)
{
	char ch;

	ch =get_first();
	while(ch != 'a' && ch != 'b' && ch != 'c' && ch != 'q')
	{
		puts("请输入正确选项");
		ch =get_first();
	}

	return ch;
}
//返回键入的第一个字母字符并清空缓存区
char get_first(void)
{
    char ch = 0;

    while (!isalpha(ch = getchar()))
        continue;
	while (getchar() != '\n')
		continue;

    return tolower(ch);	 //返回小写值
}
//注册函数
void register_user()
{
	FILE * fp;
	user new_, old;		//这里new后面多'_'的原因是c++有个关键字是new
	char temp[SIZE]; 

	show_line("请开始注册您的账号!");
	
	if ((fp = fopen("users", "r")) == NULL)
	{
		fprintf(stderr, "读取用户信息失败!\n");
		system("sleep 3s");
		return;
	}
	puts("请输入您的账号:");
	s_gets(new_.id, SIZE);
	while (!feof(fp))
	{
		fread(&old, sizeof(user), 1, fp);
		decipher(old.pwd);
		if (!strcmp(new_.id, old.id))
		{
			fprintf(stderr, "账号重复!\n");
			system("sleep 3s");
			return;
		}
	}
	puts("请输入您的密码:");
	secret_pwd(new_.pwd);
	puts("请再次输入您的密码:");
	secret_pwd(temp);
	while (1)
	{
		if (!strcmp(new_.pwd, temp))
			break;
		puts("两次密码不一致!");
		puts("请重新输入您的密码:");
		secret_pwd(new_.pwd);
		puts("请再次输入您的密码:");
		secret_pwd(temp);
	}
	puts("请输入您的电话号码以便找回密码:");
	new_.tele = get_tele();
	fp = fopen("users", "a");
	encipher(new_.pwd);
	fwrite(&new_, sizeof(user), 1, fp);
	printf("账号%s已注册成功!\n", new_.id);
	system("sleep 3s");
	
	fclose(fp);
	return;
}
//安全地获取电话号码
//64位架构下long最大值是9223372036854775807,用来存储电话号码很合适
long get_tele()
{
	long input;
	char ch;

	while (scanf("%ld", &input) != 1) 
	{
		while ((ch =getchar()) != '\n')
			putchar(ch);
		printf(" 不是一个电话号码!\n请您重新输入:\n");
	}

	return input;
}
//登录函数
void login()
{
	FILE * fp;
	user old;
	char temp[SIZE];

	show_line("请开始登录您的账号!");

	if ((fp = fopen("users", "r")) == NULL)
	{
		fprintf(stderr, "读取用户信息失败!\n");
		system("sleep 3s");
		return;
	}
	puts("请输入您的账号:");
	s_gets(temp, SIZE);
	while (!feof(fp))	//判断是否到达文件结尾
	{
		fread(&old, sizeof(user), 1, fp);
		decipher(old.pwd);
		if (!strcmp(temp, old.id))
		{
			puts("请输入您的密码:");
			secret_pwd(temp);
			if (!strcmp(temp, old.pwd))
			{
				show_line("登录成功!");
				system("sleep 2s");	//休眠,用起来比较带感哈哈哈哈
				exit(0); //想要换页面就在这里做文章
			}
			else
			{
				puts("密码不匹配!");
				system("sleep 3s");
				return;
			}
		}
	}
	printf("账号%s不存在!\n", temp);
	system("sleep 3s");

	fclose(fp);
	return;
}
//找回密码函数
void find_pwd()
{
	FILE * fp;
	user old;
	char temp[SIZE];
	long key;

	show_line("请开始找回您的密码!");

	if ((fp = fopen("users", "r")) == NULL)
	{
		fprintf(stderr, "读取用户信息失败!\n");
		system("sleep 3s");
		return;
	}

	puts("请输入您的账号:");
	s_gets(temp, SIZE);
	while (!feof(fp))
	{
		fread(&old, sizeof(user), 1, fp);
		decipher(old.pwd);
		if (!strcmp(temp, old.id))
		{
			puts("请输入您的电话号码:");
			if ((key = get_tele()) == old.tele)
				printf("您的密码是:%s\n", old.pwd);
			else
				puts("电话号码不匹配!");
			system("sleep 3s");
			return;
		}
	}
	printf("账号%s不存在!\n", temp);
	system("sleep 3s");

	fclose(fp);
	return;
}

char * s_gets(char * st, int n)
{
	char * ret_val;
	int i = 0;

	ret_val = fgets(st, n, stdin);
	if (ret_val != NULL)
	{
		while (st[i] != '\0' && st[i] != '\n')
			i++;
		if (st[i] == '\n')
			st[i] = '\0';
		else
			while (getchar() != '\n')
				continue;
	}
	return ret_val;
}
//自定义的getch()函数
char getch()
{
	char ch;

    system("stty -echo");
    system("stty -icanon");
    ch = getchar();
    system("stty icanon");
    system("stty echo");

    return ch;
}

void secret_pwd(char * pwd)
{
	char ch;
	int i = 0;

	while ((ch = getch()) != '\n')
	{
		if (ch == '\x7F')
		{
			putchar('\b');
			putchar(' ');
			putchar('\b');
			if (i)
				i--;
			else
				putchar('\a');
		}
		else
		{
			putchar('*');
			pwd[i++] = ch;
		}
	}
	pwd[i] = '\0';
	putchar('\n');

	return;
}
//加密函数
void encipher(char * original)
{
    int key = 1;

    for (int i = 0; i < strlen(original); i++)
    {
		original[i] += key;
		key=-key;
    }

	return;
}
//解密函数
void decipher(char * cipher)
{
    int key = -1;
    for (int i = 0; i < strlen(cipher); i++)
    {
        cipher[i] += key;
        key = -key;
    }

	return;
}
//展示某句话
void show_line(const char * line)
{
	system("clear");	//清屏函数
	for (int i =0; i < 40;i++)
		putchar('*');
	putchar('\n');
	printf("\n%s\n\n", line);
	for (int i =0; i < 40;i++)
		putchar('*');
	putchar('\n');	

	return;
}

void user_menu()
{
	char choice;			//记录get_choice()返回值

	show_line("欢迎使用Linux版登录系统!");
//用字符串来输出是一个比较好用的技巧,来保证对齐
    printf("\n%-20s%-20s\n%-20s%-20s\n\n", "a. 注册账号", "b. 登录账号", "c. 找回密码", "q. 退出登录");
	for (int i =0; i < 40;i++)
		putchar('*');
	putchar('\n');
	create_user_file();
	while ((choice = get_choice()) != 'q')
	{
		switch(choice)
		{
			case 'a': register_user();
					  break;
			case 'b': login();
					  break;
			case 'c': find_pwd();
					  break;
		}
		show_line("欢迎使用Linux版登录系统!");
	    printf("\n%-20s%-20s\n%-20s%-20s\n\n", "a. 注册账号", "b. 登录账号", "c. 找回密码", "q. 退出登录");
		for (int i =0; i < 40;i++)
		putchar('*');
     	putchar('\n');
	}

	return;
}
  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Linux下使用C语言实现多人会话聊天室需要基于网络编程的一些知识和技术。下面是具体的功能实现: 1. 注册与登录系统:聊天室的用户需要进行注册和登录才能使用。通过使用TCP协议,可以使用Socket编程在服务器端实现注册和登录功能。用户可以通过客户端向服务器发送注册信息,服务器将注册信息保存到数据库中。对于登录功能,用户输入用户名和密码后,服务器端验证登录信息,如果验证通过则将用户标记为已登录。 2. 建立连接与断开连接:在多人会话聊天室中,用户需要可以与服务器建立连接并断开连接。这可以通过使用TCP协议和Socket编程来实现。用户在客户端输入服务器的IP地址和端口号后,客户端与服务器建立连接。断开连接时,用户可以发送指定命令给服务器端关闭与服务器的连接。 3. 聊天功能:在多人会话聊天室中,用户可以发送消息给其他用户。这可以通过使用TCP协议和Socket编程来实现。客户端向服务器发送聊天消息,服务器收到消息后将消息广播给所有在线用户。其他用户通过服务器转发的消息进行聊天。 4. 用户管理:多人会话聊天室需要管理用户信息,包括用户的注册信息、在线状态等。服务器将用户的注册信息保存到数据库中,并记录用户的登录状态。服务器端可以实时检测用户的连接状态,并及时更新用户的在线状态。 以上是在Linux下使用C语言实现多人会话聊天室的基本功能。通过网络编程和C语言的结合,可以实现一个简单而功能完善的多人会话聊天室。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值