1.什么是文件型指针?通过文件指针访问文件有什么好处?
🌵文件型指针是一种特殊类型的指针,用于访问和操作文件。
🌵文件型指针的主要特点和优点:
文件型指针可以标识打开的文件,用于进行文件的读写操作。它存储了文件在内存中的位置信息。
通过文件型指针可以方便地对文件进行读写操作,无需每次都指定文件名和路径。只需要使用指针就可以访问文件。
文件型指针支持随机访问文件,可以直接跳转到文件任意位置进行读写。而不像流式访问只能顺序读写。
文件型指针可以同时打开多个文件,通过不同的指针分别进行文件的读写操作管理。
使用文件指针可以方便实现文件的移动、复制、删除等高级文件操作。
与直接使用文件名相比,文件指针访问文件性能更高,不需要每次进行路径解析等开销。
文件指针作为一个值类型的数据,更易于函数的参数传递和返回,实现对文件的抽象访问。
所以总的来说,通过文件型指针可以更高效地管理和操作文件,实现文件的随机访问,并支持对多个文件的同时操作,相比直接使用文件名更加灵活方便。这是使用文件指针的主要优点。
2.对文件的打开与关闭的含义是什么?为什么要打开和关闭文件?
🌵文件打开和关闭的含义如下:
- 打开文件:
文件打开指的是在程序中建立一个与某个文件对应的文件对象,以便能够对该文件进行读写操作。
打开文件需要指定文件的路径和名称,以及打开文件的模式,如只读、只写或读写等。打开文件后,程序就可以通过文件对象来读取文件内容或写入文件内容了。
- 关闭文件:
关闭文件是释放与该文件对应的文件对象。当文件使用完毕后,需要关闭文件,以释放系统资源。
比如在打开一个文本文件进行读写操作后,使用完毕后需要关闭该文件,以便系统可以释放与该文件相关联的内存和文件句柄等资源,以便为其他程序提供资源。
🌵为什么要打开和关闭文件:
打开文件是为了能够对文件进行读写操作。如果不打开文件,程序无法访问文件内容。
关闭文件是为了释放与文件相关的系统资源。如果不关闭打开的文件,文件句柄和内存将一直被占用,影响其他程序的运行。
正常的文件操作流程是:打开文件->进行读写->关闭文件。这可以保证文件资源的有效使用和释放。
所以总的来说,打开文件是为了读写文件,关闭文件是为了释放系统资源,两者配合使用可以保证文件操作的正常进行。
3.从键盘输入一个字符串,将其中的小写字母全部转换成大写字母,然后输出到一个磁盘文件test中保存,输入的字符串以“!”结束。
#include <stdio.h> int main() { FILE* fp = NULL; fp = fopen("test.txt", "w"); if (fp == NULL) { printf("Open File Error.\n"); return -1; } char ch; while ((ch = getchar()) != '!' && ch != EOF) { if (ch >= 'a' && ch <= 'z') ch -= 32; fputc(ch, fp); } fclose(fp); return 0; }
4.有两个磁盘文件A 和B,各存放一行字母,今要求把这两个文件中的信息合并(按字母顺序排列),输出到一个新文件C中去。
#include <stdio.h> #include <string.h> #include <stdlib.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); } //将A文件和B文件中的字符串读到缓冲区中 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; } } } } //将排好序的字符串写入C文件 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);//将A文件和B文件中的字符串读到缓冲区中 SortBufferChar(buffer);//排序 SaveFile(fpc, buffer);//将排好序的字符串写入C文件 CloseFile(fpa, fpb, fpc);//关闭文件 return 0; }
5.有5个学生,每个学生有3门课程的成绩,从键盘输入学生数据(包括学号,姓名,3门课程成绩),计算出平均成绩,将原有数据和计算出的平均分数存放在磁盘文件 stud中。
#include <stdio.h> typedef struct student { int num; //学号 char name[32]; //姓名 int score[3]; //成绩 float avg; //平均分 }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 (NULL == fp) { printf("打开文件失败\n"); return -1; } //将数据写入文件 for (int i = 0; i < 5; i++) { fprintf(fp, "%3d %10s %3d %3d %3d %3.2f\n", stu[i].num, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2], stu[i].avg); } fclose(fp); return 0; }
6.将第5题 stud文件中的学生数据,按平均分进行排序处理,将已排序的学生数据存入一个新文件stu_sort中。
#include <stdio.h> #include <string.h> typedef struct student { int num; //学号 char name[32]; //姓名 int score[3]; //成绩 float avg; //平均分 }student; void ReadData(student* stu) { FILE* fp = fopen("stud.txt", "r"); if (NULL == fp) { printf("打开文件失败\n"); return -1; } //读入数据 for (int i = 0; i < 5; i++) { fscanf(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 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 - 1 - i; j++) { if (stu[j].avg < stu[j + i].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 (NULL == fp) { printf("打开文件失败\n"); return -1; } //写入数据 for (int i = 0; i < 5; i++) { fprintf(fp, "%3d %10s %3d %3d %3d %3.2f\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门课程成绩,程序先计算新插入学生的平均成绩,然后将它按成绩高低顺序插入,插入后建立一个新文件。
#include <stdio.h> #include <string.h> typedef struct student { int num; //学号 char name[32]; //姓名 int score[3]; //成绩 float avg; //平均分 }Student; void TnputData(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 ReadData(Student* stu) { FILE* fp = fopen("stu_sort.txt", "r"); if (NULL == fp) { printf("打开文件失败\n"); return -1; } //读入数据 for (int i = 0; i < 5; i++) { fscanf(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 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)); } void WriteData(Student* stu) { FILE* fp = fopen("stu_new_sort.txt", "w"); if (NULL == fp) { printf("打开文件失败\n"); return -1; } //写入数据 for (int i = 0; i < 6; i++) { fprintf(fp, "%3d %10s %3d %3d %3d %3.2f\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 new_stu;//新学生 TnputData(&new_stu); Student old_stu[6]; ReadData(old_stu); InsertData(old_stu, &new_stu, 5); WriteData(old_stu); return 0; }
8.将第7题结果仍存入原有的 stu_sort文件而不另建立新文件。
#include <stdio.h> #include <string.h> typedef struct student { int num; //学号 char name[32]; //姓名 int score[3]; //成绩 float avg; //平均分 }Student; static int count; void TnputData(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 ReadData(Student** stu) { FILE* fp = fopen("stu_sort.txt", "r"); if (NULL == fp) { printf("打开文件失败\n"); return -1; } //读出数据的条数 fscanf(fp, "%d", &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\n", &pstu[i].num, pstu[i].name, &pstu[i].score[0], &pstu[i].score[1], &pstu[i].score[2], &pstu[i].avg); } fclose(fp); } 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)); } void WriteData(Student* stu) { FILE* fp = fopen("stu_sort.txt", "w"); if (NULL == fp) { printf("打开文件失败\n"); return -1; } //写入数据 fprintf(fp, "%d\n", count + 1);//先写出记录的条数 for (int i = 0; i < count + 1; i++) { fprintf(fp, "%3d %10s %3d %3d %3d %3.2f\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); } int main() { Student new_stu;//新学生 TnputData(&new_stu); Student *old_stu; ReadData(&old_stu); InsertData(old_stu, &new_stu, count); WriteData(old_stu); return 0; }
9.有一磁盘文件 employee,内存放职工的数据。每个职工的数据包括职工姓名、职工号、性别、年龄、住址、工资、健康状况、文化程度。今要求将职工名、工资的信息单独抽出来另建一个简明的职工工资文件。
#include <stdio.h> #include <stdlib.h> typedef struct employee { int num; char name[10]; int age; char addr[128]; char sex[6]; char health[10]; int salary; char class[10]; }employee; int main() { employee emp; FILE* fpIn = fopen("employee.txt", "r"); if (NULL == fpIn) { perror("fopen"); return -1; } FILE* fpOut = fopen("emp_salary.txt", "w"); if (NULL == fpOut) { perror("fopen"); fclose(fpIn); fpIn = NULL; return -1; } //读出数据并抽出相应的数据进行写入 while (!feof(fpIn)) { int count = fscanf(fpIn, "%d %s %d %s %s %s %d %s", &emp.num, emp.name, &emp.age, emp.addr, emp.sex, emp.health, &emp.salary, emp.class); if (count == -1) break; fprintf(fpOut, "%s %d\n", emp.name, emp.salary); } fclose(fpIn); fclose(fpOut); fpIn = NULL; fpOut = NULL; return 0; }
10. 从第9题的“职工工资文件”中删去一个职工的数据,再存回原文件。
#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 (NULL == fp) { perror("fopen"); 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); fp = NULL; //输入名字,进行删除 char name[32] = { 0 }; printf("请输入要删除的职工名字:"); scanf("%s", name); fp = fopen("emp_salary.txt", "w"); if (NULL == fp) { perror("fopen"); 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[i].salary); } fclose(fp); fp = NULL; return 0; }
11.从键盘输入若干行字符(每行长度不等),输入后把它们存储到一磁盘文件中。再从该文件中读入这些数据,将其中小写字母转换成大写字母后在显示屏上输出。
#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 (NULL == fp) { perror("fopen"); 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 = NULL; //读出数据,进行数据转换 fp = fopen("letter.txt", "r"); if (NULL == fp) { perror("fopen"); return -1; } while (!feof(fp)) { memset(buf, 0, 128); fgets(buf, 128, fp); ToUpper(buf); printf("%s", buf); } fclose(fp); fp = NULL; return 0; }