文件操作

c++ 文件定位,查找,修改文件指定内容fstream,seekp,seekg,tellg,tellk

实现功能:在文件查找到指定登录名,修改指定登陆名的密码
文件操作_第1张图片

因为之前我也遇到了这个查找文件的某个内容,然后修改文件的某些内容,看了很多篇子都没有看到这块内容。自己发这个博客,为帮助大家解决问题也为了给自己代码留一个副本。

第一次发的博客若有什么不足还请指正,代码全是自己手打测试过的,可以直接拷贝测试运行试试
一,解释一下这几个函数的意思
tellp 用于返回写入位置,tellg 则用于返回读取位置。不管是tellp还是tellg返回的都是记录文件的某个位置,也就是说读取位置和写入位置是一个东西,就是表示某个文件的位置,我也就可以用某个读取文位置去设置某个写入位置的值(如fp.seekp(fp.tellg());)

seekp()和seekg()函数功能
seekp:设置输出文件流的文件流指针位置
seekg:设置输入文件流的文件流指针位置
函数原型:
无偏移
ostream& seekp( streampos pos );
istream& seekg( streampos pos );
有偏移,如果off负的,就往前面偏移,反之
ostream& seekp( streamoff off, ios::seek_dir dir );
istream& seekg( streamoff off, ios::seek_dir dir );
函数参数
pos:新的文件流指针位置值
off:需要偏移的值
dir:搜索的起始位置
dir参数用于对文件流指针的定位操作上,代表搜索的起始位置
在ios中定义的枚举类型:
enum seek_dir {beg, cur, end};
每个枚举常量的含义:
ios::beg:文件流的起始位置
ios::cur:文件流的当前位置
ios::end:文件流的结束位置

二,案例
简单做了一个账户登录平台有以下功能(所有的信息都是保存在account.txt文件下)
注:账号信息的保存格式
caccount[20] \t cpassword[20] \t cquestion[30] \t canswer[30] \n

文件操作_第2张图片

1、登录
2、注册
3、找回密码(通过回答密保问题)
设置了5个函数

fstream查找修改文件内容的实例在void changeAccount();函数中,其他函数的文件操作用的c语言的文件操作可以结合做参考对比

void fileinit();//文件初始化
int startgo();//功能选择
int login();//登陆
bool chcekAccount();//验证账号密码
void logonAccount();//注册账号信息
void changeAccount();//找回密码

#define _CRT_SECURE_NO_WARNINGS
#include 
#include
#include
using namespace std;

void fileinit();//文件初始化
int startgo();//功能选择
int login();//登陆
bool chcekAccount();//验证账号密码
void logonAccount();//注册账号信息
void changeAccount();//找回密码


int main() {
     
	fileinit();
	startgo();
}
int startgo() {
     
	system("cls");
	while (true) {
     
		system("cls");
		int flag;
		char account_number[20], password[20];
		printf("\t\t1注册 2登陆 3找回密码");
		printf("\n\t\t请选择序号: ");
		scanf("%d", &flag);
		system("cls");
		if (flag == 1) {
     
			logonAccount();
		}
		else if (flag == 2) {
     
			if (login()) {
     
				break;
			}
		}
		else if (flag == 3) {
     
			changeAccount();
		}
	}
	return 1;
}
int login()
{
     
	int n = 0;
	while (TRUE)
	{
     
		if (chcekAccount())
		{
     
			printf("\t\t欢迎进入系统,请稍候......\n");
			Sleep(1000);
			return 1;
		}
		else
		{
     
			printf("\t\t密码输入错误,按任意键请重新输入\n\n");
			system("pause");
			n++;
			if (n >= 3)
			{
     
				printf("\t\t连续输错3次,程序即将退出......\n");
				Sleep(2000);
				exit(ERROR);
			}
		}
	}
}
void fileinit() {
     
	fstream fp("account.txt", std::ios::_Nocreate);
	//若文件不存在
	if (!fp.is_open()) {
     
		string t = "登陆名\t密码\t密保问题\t\t密保答案\n";
		ofstream tfp("account.txt");
		tfp << t;
		tfp.close();
	}

}
bool chcekAccount()
{
     
	char account_number[20], password[20];
	system("cls");
	printf("\t\t账号:");
	scanf("\n%s", &account_number);
	printf("\t\t密码:");
	scanf("\n%s", &password);
	bool flag = false;
	char caccount[20], cpassword[20], cquestion[30], canswer[30];
	FILE* fp = fopen("account.txt", "r");
	if (fp == NULL)
	{
     
		fp = fopen("account.txt", "w");
	}
	while (fscanf(fp, "%s\t%s\t%s\t%s\n", caccount, cpassword, cquestion, canswer) != EOF && flag == false)
	{
     
		if ((strcmp(account_number, caccount) == 0) && (strcmp(password, cpassword) == 0)) {
     
			flag = true;
		}
	}
	fclose(fp);
	return flag;
}
void logonAccount()
{
     
	printf("\t\t正在进行注册账号......\n");
	char account_number[20], password[20], question[30], answer[30];
	bool flag = 0;
	FILE* fp = fopen("account.txt", "a+");
	printf("\t\t账号:");
	getchar();
	scanf("\n%s", &account_number);
	printf("\t\t密码:");
	scanf("\n%s", &password);
	printf("\t\t密保问题:");
	scanf("\n%s", &question);
	printf("\t\t答案:");
	scanf("\n%s", &answer);
	fprintf(fp, "%s\t%s\t%s\t%s\n", account_number, password, question, answer);
	fclose(fp);
	printf("\t\t注册成功!!\n\t\t即将返回登陆界面");
	Sleep(1000);
}
void changeAccount() {
     
	printf("\t\t正在进行找回密码......\n");
	fstream fp("account.txt", ios::in | ios::out | ios::binary);
	char account_number[20], password[20], answer[30];
	printf("\t\t账号:");
	scanf("%s", &account_number);
	if (!fp.is_open())
	{
     
		printf("open file fail");
		system("pause");
	}
	bool flag = false;//是否已经修改
	char c;
	char caccount[20], cpassword[20], cquestion[30], canswer[30];//存储登录名 密码 密保问题 密保答案
	while (!fp.eof() && flag == 0) {
     
		fp >> caccount;
		fp.get();//读\t
		//存储格式caccount[20] \t cpassword[20] \t cquestion[30] \t canswer[30] \n
		if (strcmp(caccount, account_number) == 0) {
     
			streamoff len = fp.tellg();//记录密码在文件的位置			
			fp >> cpassword;
			c = fp.get();	//读\t
			fp >> cquestion;
			c = fp.get(); //读\t
			fp >> canswer;
			c = fp.get(); //读\n
			int t = 0;
			while (true) {
     
				t++;
				printf("\n\t\t密保问题:%s?", cquestion);
				printf("\n\t\t请输入你的密保答案:");
				scanf("%s", &answer);
				if (strcmp(answer, canswer) == 0)
				{
     
					printf("\n\t\t验证成功......");
					while (true) {
     
						printf("\n\t\t输入新的密码:");
						scanf("%s", &password);
						char t[30];
						printf("\n\t\t请再次输入新的密码:");
						scanf("%s", &t);
						if (strcmp(t, password) == 0) {
     
							break;
						}
						else {
     
							printf("\n\t\t两次输入密码不一致请重新输入");
						}
					}
					fp.seekp(len);
					fp << password;
					//如果修改后内容变短会出现问题,所以用用空格补上,当然如果更长,就不会有影响,可以试着把这条for语言注释后,看看效果
					for (int i = strlen(password); i < (int)strlen(cpassword); i++) {
     
						fp.write(" ", 1);
					}
					flag = 1;
					break;
				}
				else printf("\n\t\t密保没有通过,请重新输入......");
				if (t >= 3) {
     
					printf("\n\t\t连续输错3次,程序即将退出......\n");
					Sleep(2000);
					exit(ERROR);
				}
			}
		}
		if (fp.eof()) {
     
			printf("\t\t改用户没有注册修改失败!!\n\t\t即将返回登陆界面");
		}
		if (flag == 0) {
     
			fp >> cpassword; c = fp.get(); fp >> cquestion; c = fp.get(); fp >> canswer; c = fp.get();
		}
	}
	if (flag == 1)printf("\t\t修改成功!!\n\t\t即将返回登陆界面");
	Sleep(1000);
	fp.close();
}

找回密码运行结果文件操作_第3张图片
文件操作_第4张图片

你可能感兴趣的:(c++,c++)