【C语言课程设计】利用结构体数组实现文件内容的增删改查

啦啦啦,又到了学习时间,现在给大家介绍结构体数关于文件内容的增删改查

我们先把相关代码写好,再使用EGE,慢慢来不着急~

----------------------------------------------------------------------------------------------------------

一.文件的打开方式(假设文件名叫list.txt)

首先我们要建立一个文件指针fp,并使用fopen()打开文件,此时fp指向了这个txt文件

FILE *fp = fopen("文件名", "r");

文本文件最好和项目存在同一个文件夹中,此时文件名就是“list.txt”,否则就要复制文件路径 , "D:\devc++\code_dev\list.txt",注意,这里的“\”要换成“/”!

读文件的方式有很多种,这里我只列举项目中会用到的——

1.“r”,表示只读文件,不可以修改文件,因为我们是要把文件中的数据读到数组中,所以“r”就可以啦

2.“rb”, 表示只读文件,用二进制方式打开,不可以修改文件,这种方式更保险,但是文件可读性差,如果你打开txt文件,会发现你看不懂,因为这是以二进制方式存的

/ /有时候使用“r”可能会出现文件未读取完整的现象,此时我们应该用“r+”

二.使用“fread()”读取文件

fread的使用:

fread(接受数据的内存地址,读取的长度(以字节为单位) ,每次读取的个数 , 文件指针);

若fread读取文件成功,会返回一个正数,读取失败会返回0或者负数,我们可以根据fread的返回值判断文件中的数据有没有读完。

这里我们以一个结构体为单位,每次读取一个结构体的大小,循环读取,将数据储存在结构体数组中

struct Course { //我们以题目管理系统为例,这个是结构体的定义
    int number; //学号
	char title[30];	//题目
	char teacherName[10];//教师名字
	char studentName[10]; //学生名字
	char need[400]; //题目要求
} courseArray[10];//建立一个结构体数组,我这里设置的是里面最多存十个题目


int r;//接受fread()的返回值
int num = 0;//num作为元素下标
r = fread(&courseArray[num], 1, sizeof(struct Course), fp);
while(r) {
	num++;//如果成功读取读取到数据,则下一个元素继续存数据
	r = fread(&courseArray[num], 1, sizeof(struct Course), fp);
}

三.使用“fwrite()”向文件中写数据

参数和fread()类似,是和fread()配套使用滴

int count = 0;//这里的count指的是数组元素下标
while(count <= num) { //读取完文件数据之后num是存储了数据的元素个数 - 1(num从0开始的)
    fwrite(&courseArray[count], sizeof(struct Course), 1, fp);
    count++;
}

-------------------------------------------------------------------------------------------------------------------------------

好的,基础操作我们都知道了,现在正是介绍文件内容的增删改查~~~~~~~~

一.文件内容的增加

以“a+”的方式打开文件,进行文件的内容添加

“a+”:可以在文件末尾加上数据

我们只需要在文件末尾加上新增的数据即可,完整代码如下:

void addCourse() { //增加内容
	//1 打开文件
	FILE* fp = fopen("list2.txt", "a+");
	if(NULL == fp) { //确保成功打开文件,否则退出系统
		printf("数据获取失败!即将退出系统...");
		Sleep(3000);
		exit(0);
	}
	struct Course temp; //建立临时储存新增数据的结构体变量
	printf("请输入要添加的题目名字:");
	scanf("%s", temp.title);
	printf("请输入要添加的要求:");
	scanf("%s", temp.need);
	printf("请输入要添加的老师名字:");
	scanf("%s", temp.tName);
	printf("请输入要添加的学生名字:");
	scanf("%s", temp.sName);
	fwrite(&(temp), 1,  sizeof(struct Course), fp);
	fclose(fp);
	printf("信息添加成功!\n");
}

二.文件内容的查阅

1.首先使用fread()将文件内容读到数组当中

2.输入想要查找的信息

例如,我想知道某某题目的要求,指导老师以及写这个题目的学生,那么我只用输入该题目名称即可

void research() {
    //查找
	FILE* fp = fopen("list2.txt", "r");
	if(NULL == fp) {
		printf("数据获取失败!即将退出系统...");
		Sleep(3000);
		exit(0);
	}
	//2 读取问文件内容并存到容器中
	int r, num = 0;
	r = fread(&courseArray[num], 1, sizeof(struct Course), fp);
	while(r) {
		num++;
		r = fread(&courseArray[num], 1, sizeof(struct Course), fp);
	}
	//3 关闭文件
	fclose(fp);
    char input[40]; //这个数组用来接收用户输入的题目
    int count = 0;
    printf("请输入想要查找的题目\n");
    scanf("%s", input);
    while(count <= num) {
        if(strcmp(courseArray[count].title, input) == 0){  //字符串的比较用strcmp();
            printf("%s\t%s\t%s\t%s\n",             
            courseArray[count].need,courseArray[count].studentName, 
            courseArray[count].title,courseArray[count].teacherName);	
        }
        else {
            count++;
        }
    
    }
    if(count > num) {
        printf("未找到该题目信息!\n");
    }
}

想要输入别的信息进行查找,只需要把输入提示信息和strcmp()修改即可

strcmp(courseArray[count].studentName, input);//假设我要查找与学生有关的信息

如果想要查看文件的全部内容,我们可以省去查找相关的代码,直接输出信息:

void lookthroughAll() {
	FILE* fp = fopen("list2.txt", "r");
	if(NULL == fp) {
		printf("数据获取失败!即将退出系统...");
		Sleep(3000);
		exit(0);
	}
	//2 读取问文件内容并存到容器中
	int r, num = 0;
	r = fread(&courseArray[num], 1, sizeof(struct Course), fp);
	while(r) {
		num++;
		r = fread(&courseArray[num], 1, sizeof(struct Course), fp);
	}
	//3 关闭文件
	fclose(fp);
	int count = 0;
	while(count <= num) {
		printf("%s\t%s\t%s\t%s\n", courseArray[count].need,         
        courseArray[count].studentName, courseArray[count].title, 
        courseArray[count].teacherName);		
		count++;
	}
}

三.文件内容的修改

就像查阅内容一样,只不过我们找到要修改的信息之后,不是输出信息,而是提示用户修改信息

printf("请输入修改之后的信息\n");
scanf("%s", input);
strcpy(courseArray[count].title, input);//使用strcpy()实现字符串内容的拷贝

修改之后的内容要重新存回文件,使用“w”的方式打开文件进行修改

(这里的w其实是重新写了list2.txt文件)

完整代码如下:

void reviseInformation() {
    //查找
	FILE* fp = fopen("list2.txt", "r");
	if(NULL == fp) {
		printf("数据获取失败!即将退出系统...");
		Sleep(3000);
		exit(0);
	}
	//2 读取问文件内容并存到容器中
	int r, num = 0;
	r = fread(&courseArray[num], 1, sizeof(struct Course), fp);
	while(r) {
		num++;
		r = fread(&courseArray[num], 1, sizeof(struct Course), fp);
	}
	//3 关闭文件
	fclose(fp);
    char input[40]; //这个数组用来接收用户输入的题目
    int count = 0;
    printf("请输入想要查找的题目\n");
    scanf("%s", input);
    while(count <= num) {
        if(strcmp(courseArray[count].title, input) == 0){  //字符串的比较用strcmp();
            printf("请输入修改之后的题目\n");
            scanf("%s", input);
            strcpy(courseArray[count].title, input);//使用strcpy()实现字符串内容的拷贝
            printf("修改成功!\n");
            break;
        }
        count++;
    }
    if(count > num) {
        printf("未找到该题目信息!\n");
    }
    fp = fopen("list2.txt", "w");
	//写入数据
	count = 0;
	while(count <= num) {
		fwrite(&courseArray[count], 1,  sizeof(struct Course), fp);
		count++;
	}
	fclose(fp);
}

四.文件内容的删除

整体思路就是找到要删除的信息之后将对应的信息,也就是字符串,重新赋值为“\0”或“无”

举个栗子:

1.删除整个数组元素的信息

被删元素后面的所有元素都往前挪一位,若原有n个元素,则向文件中读入n - 1个元素

void deleteCourse() {
	//删除整个题目
	FILE* fp = fopen("list2.txt", "r");
	if(NULL == fp) {
		printf("数据获取失败!即将退出系统...");
		Sleep(3000);
		exit(0);
	}
	//2 读取问文件内容并存到容器中
	int r, num = 0;
	r = fread(&courseArray[num], 1, sizeof(struct Course), fp);
	while(r) {
		num++;
		r = fread(&courseArray[num], 1, sizeof(struct Course), fp);
	}
	fclose(fp);
	char input[40]; //这个数组用来接收用户输入的题目
	int count = 0;
	printf("请输入想要删除的题目\n");
	scanf("%s", input);
	while(count <= num) {
		if(strcmp(courseArray[count].title, input) == 0) { //字符串的比较用strcmp();
			for(; count < num; count++) {
				strcpy(courseArray[count].title, courseArray[count + 1].title);
				strcpy(courseArray[count].need, courseArray[count + 1].need);
				strcpy(courseArray[count].teacherName, courseArray[count + 1].tName);
				strcpy(courseArray[count].studentName, courseArray[count + 1].sName);
			}
			printf("删除成功!\n");
			break;
		} else {
			count++;
		}
	}
	if(count > num) {
		printf("未找到该题目信息!\n");
	}
	fp = fopen("list2.txt", "w");
	//写入数据
	count = 0;
	while(count < num) {
		fwrite(&courseArray[count], 1,  sizeof(struct Course), fp);
		count++;
	}
	fclose(fp);
}

2.删除部分信息

删除部分信息实质上是对信息的修改

比如想删除部分题目要求,可以在先输入对应题目,找到后再使用strcpy()

例如,原要求是:使用链表,实现二进制转换

如果要删除“使用链表”,则用strcpy()将“实现二进制转换”copy过去即可

又比如想删除某某题目的老师信息,我们可以把对应的老师名字利用strcpy()换成“暂无”;

注意:1.打开文件后我们要检查是否打开成功

if(NULL == fp) {
    printf("文件打开失败!即将退出系统");
    Sleep(3000); //暂停3秒,否则还没看到提示信息就退出程序了
    exit(0); //结束程序运行
}

2.文件读取或修改之后要j及时把文件关闭(就像你出门时要锁门一样):fclose(fp);

本期博客到这里就结束啦,下一篇再见!886~

---------------------------------------------------------------------------------------

下一篇预告:使用链表

  • 39
    点赞
  • 221
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
C语言结构体数组可以用来设计教务管理系统的增删改查功能。下面是一个简单的示例: 1. 定义结构体类型: ```c typedef struct { char name[20]; int studentID; float score; } Student; ``` 2. 声明结构体数组并初始化: ```c Student students[100]; // 假设最多有100个学生 int count = 0; // 记录当前学生数量 // 添加学生信息 strcpy(students[count].name, "张三"); students[count].studentID = 1001; students[count].score = 90.5; count++; strcpy(students[count].name, "李四"); students[count].studentID = 1002; students[count].score = 85.0; count++; ``` 3. 实现增加学生信息的功能: ```c void addStudent() { if (count >= 100) { printf("学生数量已达上限,无法添加新学生。\n"); return; } printf("请输入学生姓名:"); scanf("%s", students[count].name); printf("请输入学生学号:"); scanf("%d", &students[count].studentID); printf("请输入学生成绩:"); scanf("%f", &students[count].score); count++; printf("学生信息添加成功。\n"); } ``` 4. 实现删除学生信息的功能: ```c void deleteStudent() { int studentID; printf("请输入要删除的学生学号:"); scanf("%d", &studentID); int i; for (i = 0; i < count; i++) { if (students[i].studentID == studentID) { // 将最后一个学生信息覆盖到要删除的位置 students[i] = students[count - 1]; count--; printf("学生信息删除成功。\n"); return; } } printf("未找到该学生学号对应的学生信息。\n"); } ``` 5. 实现修改学生信息的功能: ```c void modifyStudent() { int studentID; printf("请输入要修改的学生学号:"); scanf("%d", &studentID); int i; for (i = 0; i < count; i++) { if (students[i].studentID == studentID) { printf("请输入新的学生姓名:"); scanf("%s", students[i].name); printf("请输入新的学生成绩:"); scanf("%f", &students[i].score); printf("学生信息修改成功。\n"); return; } } printf("未找到该学生学号对应的学生信息。\n"); } ``` 6. 实现查询学生信息的功能: ```c void queryStudent() { int studentID; printf("请输入要查询的学生学号:"); scanf("%d", &studentID); int i; for (i = 0; i < count; i++) { if (students[i].studentID == studentID) { printf("学生姓名:%s\n", students[i].name); printf("学生成绩:%.2f\n", students[i].score); return; } } printf("未找到该学生学号对应的学生信息。\n"); } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值