第10章——对文件的输入输出

1.什么是文件型指针?通过文件指针访问文件有什么好处?

每个被使用的文件都在内存中开辟一个相应的文件信息区,用来存放文件的有关信息。这些信息是保存在一个结构体变量中的。该结构体类型是由系统声明的,取名为FILE。
通过文件指针访问文件的好处是:可以随机访问文件,有效表示数据结构,动态分配内存,方便使用字符串,有效使用数组。

2.对文件的打开和关闭的含义是什么?为什么要打开和关闭文件?

打开是指为文件建立相应的信息区和文件缓冲区,使文件的指针变量指向文件,从而进行读写操作,关闭是撤销文件信息区和文件缓冲区,使文件的指针变量不在指向文件,就无法进行读写操作了,对文件读写之前应该打开该文件,打开文件,才能对文件进行操作,在使用结束之后应关闭,不然可能会导致缓冲区数据丢失。

3.从键盘输入一个字符串,将其中的小写字母全部转换成大写字母,然后输出到一个磁盘文件test中保存,输入的字符串以“!”结束。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int main()
{
	FILE* fp = NULL;
	fp = fopen("test.txt", "w");
	if (NULL == fp) {
		printf("Open File Eorror.\n");
		return -1;
	}

	//输入字符串并进行转换
	char ch;
	while ((ch = getchar()) != '!' && ch != EOF) { //end of file
		if (ch >= 'a' && ch <= 'z') //小写字母转换大写字母
			ch -= 32;
		fputc(ch, fp);
	}
	fclose(fp);
	return 0;
}

4.有两个磁盘文件A和B,各存放一行字母,今要求把这两个文件中的信息合并(按字母顺序排列),输出到一个新文件C中去。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

void OpenFile(FILE** fpa, FILE** fpb, FILE** fpc)
{
	*fpa = fopen("A.txt", "r");
	if (NULL == fpa) {
		printf("Open A.txt File Error.\n");
		exit(1);
	}
	*fpb = fopen("B.txt", "r");
	if (NULL == fpb) {
		printf("Open B.txt File Error.\n");
		exit(1);
	}
	*fpc = fopen("C.txt", "w");
	if (NULL == fpc) {
		printf("Open C.txt File Error.\n");
		exit(1);
	}
}

void CloseFile(FILE* fpa, FILE* fpb, FILE* fpc)
{
	fclose(fpa);
	fclose(fpb);
	fclose(fpc);
}

void GetBufferChar(FILE* fpa, FILE* fpb, char* buffer)
{
	fgets(buffer, 1024, fpa); //从A文件中读取数据
	int len = strlen(buffer);
	fgets(buffer + len, 1024 - len, fpb); //从B文件读取数据

}
void SortBufferChar(char* buffer)
{
	//冒泡排序
	int n = strlen(buffer);
	for (int i = 0; i < n - 1; i++) {
		for (int j = 0; j < n - i - 1; j++) {
			if (buffer[j] > buffer[j + 1]) {
				char tmp = buffer[j];
				buffer[j] = buffer[j + 1];
				buffer[j + 1] = tmp;
			}
		}
	}
}
void SaveFile(FILE* fpc, char* buffer)
{
	fputs(buffer, fpc);
}

int main()
{
	FILE* fpa, * fpb, * fpc;
	OpenFile(&fpa, &fpb, &fpc);
	char buffer[1024] = { 0 };
	GetBufferChar(fpa, fpb, buffer);
	SortBufferChar(buffer);
	SaveFile(fpc, buffer);
	CloseFile(fpa, fpb, fpc);
	return 0;
}

5.有5个学生,每个学生有3门课程的成绩,从键盘输入学生数据(包括学号,姓名,3门课程成绩),计算出平均成绩,将原有数据和计算出的平均分数存放在磁盘文件stud中。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

typedef struct Student
{
	int num; //学号
	char name[32]; //名字
	int score[3]; //3门课程的成绩
	float avg; //3门课程的平均分
}Student;
int main()
{
	Student stu[5]; //创建5个学生的结构体
	for (int i = 0; i < 5; i++) {
		printf("num name score1 score2 score3\n");
		scanf("%d %s %d %d %d", &stu[i].num, stu[i].name, &stu[i].score[0],
			&stu[i].score[1], &stu[i].score[2]);
		//计算平均分
		stu[i].avg = (stu[i].score[0] + stu[i].score[1] + stu[i].score[2]) / 3.0;
	}

	FILE* fp = fopen("stud.txt", "w");
	if (fp == NULL) {
		printf("打开文件失败.\n");
		return -1;
	}
	//将数据写入文件
	for (int i = 0; i < 5; i++) {
		fprintf(fp, "%d %s %d %d %d %f\n", stu[i].num, stu[i].name, stu[i].score[0],
			stu[i].score[1], stu[i].score[2], stu[i].avg);
	}
	return 0;
}

6.将第5题stud文件中的学生数据,按平均分进行排序处理,将已排序的学生数据存入一个新文件stu_sort中。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

typedef struct Student
{
	int num; //学号
	char name[32]; //名字
	int score[3]; //3门课程的成绩
	float avg; //3门课程的平均分
}Student;

void ReadData(Student* stu)
{
	FILE* fp = fopen("stud.txt", "r");
	if (fp == NULL) {
		printf("打开文件失败.\n");
		return -1;
	}
	//读取数据
	for (int i = 0; i < 5; i++) {

		fscanf(fp, "%d %s %d %d %d %f", &stu[i].num, stu[i].name, &stu[i].score[0],
			&stu[i].score[1], &stu[i].score[2], &stu[i].avg);
	}
	fclose(fp);
}

void SortData(Student* stu, int n)
{
	Student tmp_stu;
	int size = sizeof(tmp_stu);
	for (int i = 0; i < n-1; i++) {
		for (int j = 0; j < n - i - 1; j++) {
			if (stu[j].avg < stu[j + 1].avg) {
				//交换结构体数据
				memcpy(&tmp_stu, &stu[j], size);
				memcpy(&stu[j], &stu[j + 1], size);
				memcpy(&stu[j + 1], &tmp_stu, size);
			}
		}
	}
}

void WriteData(Student* stu)
{
	FILE* fp = fopen("stu_sort.txt", "w");
	if (fp == NULL) {
		printf("打开文件失败.\n");
		return -1;
	}
	//写入数据
	for (int i = 0; i < 5; i++) {
		fprintf(fp, "%d %s %d %d %d %f\n", stu[i].num, stu[i].name, stu[i].score[0],
			stu[i].score[1], stu[i].score[2], stu[i].avg);
	}
	fclose(fp);
}
int main()
{
	Student stu[5];
	ReadData(stu);
	SortData(stu, 5);
	WriteData(stu);
	return 0;
}

7.将第6题中已排序的学生成绩文件进行插入处理。插入一个学生的3门课程成绩,程序先计算新插入的学生的平均成绩,然后将它按成绩高低顺序插入,插入后建立一个新文件。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

typedef struct Student
{
	int num; //学号
	char name[32]; //名字
	int score[3]; //3门课程的成绩
	float avg; //3门课程的平均分
}Student;

void ReadData(Student* stu)
{
	FILE* fp = fopen("stu_sort.txt", "r");
	if (fp == NULL) {
		printf("打开文件失败.\n");
		return -1;
	}
	//读取数据
	for (int i = 0; i < 5; i++) {

		fscanf(fp, "%d %s %d %d %d %f", &stu[i].num, stu[i].name, &stu[i].score[0],
			&stu[i].score[1], &stu[i].score[2], &stu[i].avg);
	}
	fclose(fp);
}

void WriteData(Student* stu)
{
	FILE* fp = fopen("stu__new_sort.txt", "w");
	if (fp == NULL) {
		printf("打开文件失败.\n");
		return -1;
	}
	//写入数据
	for (int i = 0; i < 6; i++) {
		fprintf(fp, "%d %s %d %d %d %f\n", stu[i].num, stu[i].name, stu[i].score[0],
			stu[i].score[1], stu[i].score[2], stu[i].avg);
	}
	fclose(fp);
}

void InputData(Student* stu)
{
	printf("请输入新学生的成绩信息:\n");
	printf("num name score1 score2 score3\n");
	scanf("%d %s %d %d %d", &(stu->num), stu->name, &(stu->score[0]),
		&(stu->score[1]), &(stu->score[2]));
	stu->avg = (stu->score[0] + stu->score[1] + stu->score[2]) / 3.0;
}

void InsertData(Student* old_stu, Student* new_stu, int n)
{
	int pos = 0;
	while (pos < n) {
		if (new_stu->avg > old_stu[pos].avg)
			break;
		pos++;
	}
	//移动数据
	for (int i = n; i > pos; i--) {
		memcpy(&old_stu[i], &old_stu[i - 1], sizeof(Student));
	}
	//在pos位置把新学生的数据插入
	memcpy(&old_stu[pos], new_stu, sizeof(Student));
}

int main()
{
	Student new_stu; //新学生
	InputData(&new_stu);
	Student old_stu[6];
	ReadData(old_stu);
	InsertData(old_stu, &new_stu, 5);
	WriteData(old_stu);
	return 0;
}

8.将第7题结果存入原有的stu_sort文件而不另建立新文件。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

typedef struct Student
{
	int num; //学号
	char name[32]; //名字
	int score[3]; //3门课程的成绩
	float avg; //3门课程的平均分
}Student;

static int count;

void ReadData(Student** stu)
{
	FILE* fp = fopen("stu_sort.txt", "r");
	if (fp == NULL) {
		printf("打开文件失败.\n");
		return -1;
	}
	//读取数据的条数
	int count;
	fscanf(fp, "%d\n", &count);
	*stu = (Student*)malloc(sizeof(Student) * (count + 1));
	Student* pstu = *stu;
	//读取数据
	for (int i = 0; i < count; i++) {

		fscanf(fp, "%d %s %d %d %d %f", &pstu[i].num, pstu[i].name, &pstu[i].score[0],
			&pstu[i].score[1], &pstu[i].score[2], &pstu[i].avg);
	}
	fclose(fp);
}

void WriteData(Student* stu)
{
	FILE* fp = fopen("stu_sort.txt", "w");
	if (fp == NULL) {
		printf("打开文件失败.\n");
		return -1;
	}
	//写入数据
	fprintf(fp, "%d\n", count + 1); //先写出记录的条数
	for (int i = 0; i < count + 1; i++) {
		fprintf(fp, "%d %s %d %d %d %f\n", stu[i].num, stu[i].name, stu[i].score[0],
			stu[i].score[1], stu[i].score[2], stu[i].avg);
	}
	fclose(fp);
	//释放学生结构空间
	free(stu);
}


void InputData(Student* stu)
{
	printf("请输入新学生的成绩信息:\n");
	printf("num name score1 score2 score3\n");
	scanf("%d %s %d %d %d", &(stu->num), stu->name, &(stu->score[0]),
		&(stu->score[1]), &(stu->score[2]));
	stu->avg = (stu->score[0] + stu->score[1] + stu->score[2]) / 3.0;
}

void InsertData(Student* old_stu, Student* new_stu, int n)
{
	int pos = 0;
	while (pos < n) {
		if (new_stu->avg > old_stu[pos].avg)
			break;
		pos++;
	}
	//移动数据
	for (int i = n; i > pos; i--) {
		memcpy(&old_stu[i], &old_stu[i - 1], sizeof(Student));
	}
	//在pos位置把新学生的数据插入
	memcpy(&old_stu[pos], new_stu, sizeof(Student));
}



int main()
{
	Student new_stu; //新学生
	InputData(&new_stu);

	Student* old_stu;
	ReadData(&old_stu);

	InsertData(old_stu, &new_stu, count);
	WriteData(old_stu);
	return 0;
}

9.有一磁盘文件employee,内存放职工的数据。每个职工的数据包括职工姓名、职工号、性别、年龄、住址、工资、健康情况、文化程度。今要求将职工名、工资的信息单独抽出来另建一个简明的职工工资文件。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

typedef struct employee
{
	int num;
	char name[32];
	char sex[4];
	int age;
	char addr[128];
	int salary;
	char health[10];
	char classes[10];
}employee;

int main()
{
	employee emp;
	FILE* fpIn = fopen("employee.txt", "r");
	if (fpIn == NULL) {
		printf("打开emplyee.txt文件失败.\n");
		return -1;
	}

	FILE* fpOut = fopen("emp_salary.txt", "w");
	if (fpOut == NULL) {
		printf("打开emp_salary.txt文件失败.\n");
		fclose(fpIn);
		return -1;
	}

	//读出数据并抽取相应的信息进行写入
	while (!feof(fpIn)) {
		int count = fscanf(fpIn, "%d %s %s %d %s %d %s %s", &emp.num, emp.name, emp.sex,
			&emp.age, emp.addr, &emp.salary, emp.health, emp.classes);
		if (count == -1) {
			break;
		}
		fprintf(fpOut, "%s %d\n", emp.name, emp.salary);
	}

	fclose(fpIn);
	fclose(fpOut);
	return 0;
}

10.从第9题的“职工工资文件”中删去一个职工的数据,再存回

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>

typedef struct emp_salary
{
	char name[32];
	int salary;
}emp_salary;

int main()
{
	emp_salary es[100];
	FILE* fp = fopen("emp_salary.txt", "r");
	if (fp == NULL) {
		printf("打开emp_salary.txt文件失败.\n");
		return -1;
	}

	int i = 0;
	while (!feof(fp)) {
		int count = fscanf(fp, "%s %d", es[i].name, &es[i].salary);
		if (count == -1) {
			break;
		}
		i++;
	}
	fclose(fp);

	//输入名字进行删除
	char name[32] = { 0 };
	printf("请输入要删除的职工的名字:");
	scanf("%s", name);
	fp = fopen("emp_salary.txt", "w");
	if (fp == NULL) {
		printf("打开emp_salary.txt文件失败.\n");
		return -1;
	}

	for (int j = 0; j < i; j++) {
		if (strcmp(name, es[j].name) == 0) {
			continue;
		}
		fprintf(fp, "%s %d\n", es[j].name, es[j].salary);
	}

	fclose(fp);
	return 0;
}

11.从键盘输入若干行字符(每行长度不等),输入后把它们存储到一磁盘文件中,再从该文件中读入这些数据,将其中小写字母转换成大写字母后再显示屏上输出。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>

void ToUpper(char* str)
{
	while (*str != '\0') {
		if (*str >= 'a' && *str <= 'z') {
			*str -= 32;
		}
		str++;
	}
}
int main()
{
	FILE* fp = fopen("letter.txt", "w");
	if (fp == NULL) {
		printf("打开文件失败。\n");
		return -1;
	}
	//输入字符串然后写入文件
	char buf[128] = { 0 };
	while (1) {
		printf("请输入字符串(如果输入exit,则退出输入):");
		gets(buf);
		if (strcmp("exit", buf) == 0)
			break;
		fprintf(fp, "%s\n", buf);
	}
	fclose(fp);

	//读出数据,进行转换输出
	fp = fopen("letter.txt", "r");
	if (fp == NULL) {
		printf("打开文件失败。\n");
		return -1;
	}
	while (!feof(fp)) {
		memset(buf, 0, 128);
		fgets(buf, 128, fp);
		ToUpper(buf);
		printf("%s", buf);
	}
	fclose(fp);
	return 0;
}
  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值