双11狂欢大促

盲盒赢 定制羽绒服

开启惊喜盲盒,抽取你的专属好礼

— 惊喜奖品抢先看 —

期末项目篇:C语言文件操作

星落化尘 星落化尘 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区

原本是没打算写这个篇章的,因为这个内容用的特别的少,忘记的很快,学起来可能两分钟就好了,就几条指令

1.基础操作

学会基础操作其实就差不多了,但是下面的内容也可以看看

下面这两个表格写代码的时候可以看看,考试前可以看看(我也不记得会不会考),不一定要回背

文件的使用
使用方式作用 如果文件不存在
"r"(只读)为了输入数据,打开一个已经存在的文本文件
出错         
"w"(只写)为了输出数据,打开一个文本文件建立一个新的文件
"a"(追加)向文本文件添加数据建立一个新的文件
"rb"(只读)为了输入数据,打开一个二进制文件
出错
"wb"(只写)为了输出数据,打开一个二进制文件
建立一个新的文件
"ab"(追加)向一个二进制文件尾添加数据
出错
"r+"(读写)
为了读和写,打开一个文本文件
出错
"w+"(读写)
为了读和写,建立一个新的文本文件
建立一个新的文件
"a+"(读写)
打开一个文本文件,在文件尾进行读写
建立一个文件
"rb+"(读写)
为了读和写,打开一个二进制文件
出错
"wb+"(读写)为了读和写,建立一个新的二进制文件
建立一个新的文件
"ab+"(读写)打开一个二进制文件,在文件尾进行读写建立一个新的文件
多敲了一行删不掉 
文件的顺序读写
函数名功能适用性
fgetc(file)字符输入函数所有输入流
fputc(char,file)字符输出函数所有输出流
fgets(char[] arr,int size,file)文本行输入函数所有输入流
fputs(char[] arr,file)文本行输出函数(覆盖原本内容)所有输出流
fscanf()格式化输入函数所有输入流(多用于结构体的输入)
fprintf()格式化输出函数所有输出流(多用于结构体的输出)
fread()二进制输入文件
fwrite()二进制输出文件

主要是把理解上面两个表格,下面写一下用法

示例代码:(只是示例代码,正常写的话对一个文件只会有写操作或是读操作,一般是不会两个一起写的!!!)

#include<stdio.h>
#include<string.h>
#include<errno.h>

typedef struct S
{
	char name[10];
	int age;
 
}Peo;
 
int main()
{
    //打开文件
	FILE* pf= fopen("test.txt", "w+");

    //fgetc(): 读入一个字符
    char ch = fgetc(pf);

    //fputc(): 输入一个字符
    fputc('a', pf);
    
	
	//fgets(): 读入指定个数的字符串
    char arr[10] = { 0 };
	fgets(arr, 5, pf); 

    //fputs(): 输入一行字符串(会覆盖)
    fputs("hello world", pf);

    //fscanf(): 输入数据,原先指定格式,后面读入数据就方便
    Peo p = { 0 };
	fscanf(pf, "%s %d", p.name, &p.age);
    
    //fprintf(): 读入数据并进行封装
    Peo p = { "zhangsan", 18 };
	fprintf(pf, "%s %d\n", p.name, p.age);
    

	//用完关闭文件
	fclose(pf);
	pf = NULL;
 
	return 0;
}

2. 期末项目(菜单功能)

那么我们通过一个示例来进一步了解该如何写一个学生成绩管理系统的菜单及数据存储功能

剩下的功能就靠大家课后自己实现啦

知识点:switch,system函数,多文件程序,文件的输入和输出

大家看的时候就学一学思路就好了,文件操作的代码比较乱,因为学长用的是visual studio写的,这个软件不用C++报错很离谱,代码全是各种查api查出来的

main.cpp(主函数)

//多文件引用
#include "student.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void insertStudent() {
	S student;
	getchar();
	printf("请输入学生姓名:\n");
	fgets(student.name,sizeof(student.name), stdin);
	printf("请输入学生成绩:\n");
	scanf_s("%d", &student.grade);
	addStudent(student);
}
void printStudent() {
	int num = 0;
	S* students = getStudents(&num);
	for (int i = 0; i < num; i++) {
		printf("%s %d\n", students[i].name, students[i].grade);
	}
	system("pause");
}

int main() {
	int chance;
	while (true) {
		//清屏
		system("cls");

		printf("欢迎使用XXXX学生成绩管理系统!\n");
		printf("请根据以下选项选择您需要的服务:\n");
		printf("1. 查询全部成绩\n");
		printf("2. 插入成绩\n");
		printf("0. 退出系统\n");
		scanf_s("%d", &chance);
		switch (chance)
		{
		case 1:
			printStudent();
			break;
		case 2:
			insertStudent();
			break;
		case 0:
			return 0;
		default:
			printf("请输入正确的选择\n");
			//暂停
			system("pause");
			break;
		}
	}
}

 

student.h(工具类的头文件)

#include<stdio.h>
#include<string.h>
#include<errno.h>
#include<stdlib.h>
//定义一个学生类(面向对象的思想)
typedef struct student {
	//只是做个演示,所以就只写了两个属性,你们自己写可以多加几个属性
	//比如学号、年龄、学科什么的
	//因为是大伙的期末作业,学长有自己的期末作业 QAQ
	char name[100];
	int grade;
}S;

S* getStudents(int* num);

void addStudent(S student);

student.cpp(工具类的实现类)

#include "student.h"


S* getStudents(int* num)
{
	FILE* filePtr = (FILE*)malloc(sizeof(FILE));
	FILE** pf = &filePtr;
	fopen_s(pf, "test.txt", "r+");
	S students[1000];
	int cnt = 0;
	if (*pf == NULL) return NULL;
	while (fscanf_s(*pf, "%s %d", students[cnt].name, sizeof(students[cnt].name), &students[cnt].grade) != EOF) {
		cnt++;
		(*num)++;
	}
	fclose(*pf);
	*pf = NULL;
	return students;
}

void addStudent(S student)
{
	//vs写这个东西很奇怪,下面的写法确实很怪
	//因为学长一直都是用C++的,所以C语言也不清楚
	//下面的api写法是查的AI
	//初始化数据----因为数据好像会覆盖,所以我们再把原本的数据读出来再书写新数据
	int num = 0;
	S* students = getStudents(&num);
	//打开文件
	FILE* filePtr = (FILE*)malloc(sizeof(FILE));
	FILE** pf = &filePtr;
	fopen_s(pf, "test.txt", "w+");
	if (*pf == NULL) return;
	for (int i = 0; i < num; i++) {
		fprintf(*pf, "%s %d\n", students[i].name, students[i].grade);
	}
	//插入数据
	fprintf(*pf, "%s %d\n", student.name, student.grade);
	//关闭文件
	fclose(*pf);
	*pf = NULL;
}

这就体现了分模块的作用,如果使用单文件的写法,所有的文件都杂在一起会使文件的后期管理成本上升(只是我们代码目前比较短所以看起来没那么复杂,学长当初的这个系统用C++写的代码也有1000行了)

因为学长用的是w+的写法,其使用起来可能没那么方便,会需要重新读入数据,但是打开txt文件是相对比较容易看懂的

如果想要简化思维上的操作,可以用"ab"的追加写法,但是其书写的文件是比较难看的

3. 总结

文件的书写是比较繁琐的一件事情,他的本地持久化存储的过程是非常接近底层的代码,且数据管理较杂乱,如果之后引入数据库的概念就可以更加轻松的实现数据的持久化。

而多文件程序框架是搭建软件架构的有个重要技术与理念,它能够大大的降低软件后期的开发和维护成本,让你的代码更清晰易懂。

本文涉及的内容比较的少,但是只要掌握了就可以完成期末的项目了,如果同学们想更深入的学习与了解可以在csdn查询其他的博客进行学习。

...全文

相关推荐

C语言期末大作业参考代码

内含C语言期末大作业参考代码《迷之学习包》,包括17届抽学号,18届抽学号,以及比较难读懂的c源程序

Cathy1122334455

★C语言期末课程设计★——学生成绩管理系统(完整项目+源代码+详细注释)

C语言期末课程设计——学生成绩管理系统,这个程序是用C语言程序编写的,运行环境为VisualC++6.0,实现了录入学生成绩信息、查找学生成绩信息、删除学生成绩信息、修改学生成绩信息、插入学生成绩信息、按总分排序并保存到文件中、学生人数功能等等,是学习C++语言程序很好的参考资料,本系统在命令行窗口运行,没有可视化界面,没有用到MFC类库,如果朋友们用来学习或做C++语言期末课程设计作业一定是可以的,我来共享给大家一些哦!!!要是觉得好的话,记得给个三连!!!亲测有效哦!!!......

小浝仔(๑>؂<๑)

C语言 文件操作解析详解及实例代码

C语言文件操作解析         在文件操作中除了打开操作以及读写操作,还有几种比较常见的操作。下面介绍一下这些操作中涉及到的函数。 一.移动位置指针的函数    rewind函数和fseek函数,这两个函数的原型是:    void rewind(FILE *fp);     将位置指针移动到文件首   int fseek(FILE *fp,long int offset,int origin);   将位置指针移动到距离origin的offset字节数的位置   其中对于fseek函数中的参数,origin为起始点,offset为距离origin的偏移字节数  origin的值有三个:S

weixin_38622467

C语言文件操作(文件操作)

C语言文件操作(文件操作) FILE *p 那些的文件操作 我经常做些大型系统需要很多文件操作

张腾元-Ternence

C语言程序设计基础 & 期末复习

C语言程序设计基础 & 期末复习

三季人 G
评论
收藏 已收藏
分享
返回顶部