c语言———标准IO fgetc fputc fprintf fscanf【内附练习及代码】
1.思维导图
2.练习
1.将源文件内容复制到目标文件
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{FILE *src_fp =fopen ("source_file.txt","r");FILE *dest_fp =fopen ("destination_file.txt","w");int ch;while((ch=fgetc(src_fp))!=EOF){ fputc(ch,dest_fp);}fclose(src_fp);fclose(dest_fp);return 0;
}
2.计算文件内行数
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{int count =0;FILE* fp = fopen("fget.txt","r");while(1){char ch =fgetc(fp);if (ch==EOF){break;}if (ch=='\n'){count++;}}printf("count:%d\n",count);fclose(fp);return 0;
}
3.学生成绩
1:使用fscanf 和 fprintf 实现文件的拷贝功能
2:先编写以下结构体
struct Student{
char name[20];
double math;
double chinese;
double english;
double physical;
double chemical;
double biological;
};
第一步:创建一个 struct Student 类型的数组 arr[3],初始化该数组中3个学生的属性
第二步:编写一个叫做save的函数,功能为
将数组arr中的3个学生的所有信息,保存到文件中去,使用fprintf实现
第三步:编写一个叫做load的函数,功能为
将文件中保存的3个学生信息,读取后,写入到另一个数组 brr 中去
第四步:编写一个叫做 show的函数,功能为
遍历输出 arr 或者 brr 数组中的所有学生的信息
第五步:编写一个叫做 setMath 的函数,功能为
修改 文件中 所有学生的数学成绩
方法一:
头文件test.h
test.h
#include <stdio.h>
#include <string.h>
#include <stdlib.h>typedef struct student{char name[20];double math;double chinese;double english;double physical;double chemical;double biological;}Stu,*StuPtr;void save(StuPtr arr ,int n);void show(StuPtr arr,int n);void load(StuPtr brr,int n);void setMath(const char *filename,double math);
#endif
源文件 test.c
test.c
#include "test.h"void save(StuPtr arr ,int n)
{FILE *fp=fopen("demo1.txt","w");if (fp==NULL){printf("打开失败");return;}for (int i=0;i<n;i++){fprintf(fp,"%s %lf %lf %lf %lf %lf %lf",arr[i].name,arr[i].math,arr[i].chinese,arr[i].english,arr[i].physical,arr[i].chemical ,arr[i].biological);}fclose(fp);
}
void load(StuPtr brr,int n)
{FILE *fp =fopen("demo1.txt","r");if (fp==NULL){printf("失败");return;}for (int i=0;i<n;i++){fscanf(fp,"%s %lf %lf %lf %lf %lf %lf",brr[i].name,&brr[i].math,&brr[i].chinese,&brr[i].english,&brr[i].physical,&brr[i].chemical ,&brr[i].biological);}fclose(fp);}
void show(StuPtr arr,int n)
{for(int i=0;i<n;i++){printf("姓名=%s\n",arr[i].name);printf("数学=%lf\n",arr[i].math);printf("语文=%lf\n",arr[i].chinese);printf("英语=%lf\n",arr[i].english);printf("物理=%lf\n",arr[i].physical);printf("化学=%lf\n",arr[i].chemical);printf("生物=%lf\n",arr[i].biological);printf("------------------\n");}}void setMath(const char *filename,double math)
{Stu arr[3]={0};load(arr,3);for (int i=0;i<3;i++){arr[i].math=math;}save(arr,3);
}
测试文件main.c
main.c
#include "test.h"int main()
{Stu arr[3] ={{"张三",78,88,98,66,87,93},{"lisi",55,66,55,55,55,55},{"wangwu",66,66,6,66,66,66}};Stu brr[3]={0};save(arr,3);load(brr,3);show(arr,3);setMath("demo1.txt",100);show(arr,3);return 0;
}
方法二:链表
头文件
#ifndef TEST_H
#define TEST_H#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 定义学生结构体
typedef struct student {char name[20];double math;double chinese;double english;double physical;double chemical;double biological;struct student *next; // 指向下一个节点
} Stu, *StuPtr;// 函数声明
void save(StuPtr head);
StuPtr load(const char *filename);
void show(StuPtr head);
void setMath(const char *filename, double math);#endif
源文件
#include "test.h"// 保存链表中的学生信息到文件
void save(StuPtr head) {FILE *fp = fopen("demo1.txt", "w");if (fp == NULL) {printf("打开失败\n");return;}StuPtr current = head;while (current) {fprintf(fp, "%s %lf %lf %lf %lf %lf %lf\n",current->name, current->math,current->chinese, current->english,current->physical, current->chemical,current->biological);current = current->next;}fclose(fp);printf("学生信息已保存到文件\n");
}// 从文件中读取学生信息到链表
StuPtr load(const char *filename) {FILE *fp = fopen(filename, "r");if (fp == NULL) {printf("文件打开失败\n");return NULL;}StuPtr head = NULL, tail = NULL;while (1) {StuPtr newStudent = (StuPtr)malloc(sizeof(Stu));if (fscanf(fp, "%s %lf %lf %lf %lf %lf %lf",newStudent->name, &newStudent->math,&newStudent->chinese, &newStudent->english,&newStudent->physical, &newStudent->chemical,&newStudent->biological) != 7) {free(newStudent);break;}newStudent->next = NULL;if (head == NULL) {head = newStudent;tail = newStudent;} else {tail->next = newStudent;tail = newStudent;}}fclose(fp);printf("学生信息已从文件加载到链表\n");return head;
}// 显示链表中的学生信息
void show(StuPtr head) {StuPtr current = head;while (current) {printf("姓名=%s\n", current->name);printf("数学=%lf\n", current->math);printf("语文=%lf\n", current->chinese);printf("英语=%lf\n", current->english);printf("物理=%lf\n", current->physical);printf("化学=%lf\n", current->chemical);printf("生物=%lf\n", current->biological);printf("------------------\n");current = current->next;}
}// 修改链表中所有学生的数学成绩并保存到文件
void setMath(const char *filename, double math) {StuPtr head = load(filename);StuPtr current = head;while (current) {current->math = math;current = current->next;}save(head);// 释放链表current = head;while (current) {StuPtr temp = current;current = current->next;free(temp);}printf("所有学生的数学成绩已修改为 %lf\n", math);
}
测试文件
#include "test.h"int main() {// 创建链表头结点StuPtr head = NULL, tail = NULL;// 初始化链表中的学生信息StuPtr student1 = (StuPtr)malloc(sizeof(Stu));strcpy(student1->name, "张三");student1->math = 78;student1->chinese = 88;student1->english = 98;student1->physical = 66;student1->chemical = 87;student1->biological = 93;student1->next = NULL;StuPtr student2 = (StuPtr)malloc(sizeof(Stu));strcpy(student2->name, "李四");student2->math = 55;student2->chinese = 66;student2->english = 55;student2->physical = 55;student2->chemical = 55;student2->biological = 55;student2->next = NULL;StuPtr student3 = (StuPtr)malloc(sizeof(Stu));strcpy(student3->name, "王五");student3->math = 66;student3->chinese = 66;student3->english = 6;student3->physical = 66;student3->chemical = 66;student3->biological = 66;student3->next = NULL;// 将学生加入链表head = student1;tail = student1;tail->next = student2;tail = student2;tail->next = student3;// 保存链表到文件save(head);// 加载学生信息到新链表StuPtr newHead = load("demo1.txt");// 显示链表中的学生信息printf("初始学生信息:\n");show(newHead);// 修改数学成绩并保存setMath("demo1.txt", 100);// 加载修改后的学生信息并显示StuPtr updatedHead = load("demo1.txt");printf("修改后的学生信息:\n");show(updatedHead);// 释放链表StuPtr current = updatedHead;while (current) {StuPtr temp = current;current = current->next;free(temp);}return 0;
}