首页计算机计算机软件C语言程序设计 10 第十章 文件.pptx

10 第十章 文件.pptx

页数:28页文件大小:365.8 KB来源: C语言程序设计ppt课件

本课件讲解C语言的文件操作,先说明输入输出的概念、文件的分类与缓冲文件系统,介绍FILE结构体与文件类型指针以及文件的操作步骤,再依次展开文件的打开与关闭、字符读写、字符串读写、格式化读写与数据块读写函数,最后讲解文件位置指针、rewind、fseek与ftell实现随机读写。

第十章文件导览页,列出文件概述类型指针开关读写与定位等主题
输入输出概念页,展示CPU内存与键盘鼠标磁盘显示器间的数据传输
文件概念页,说明文件是外部介质上数据集合及使用数据文件的四点目的
查看本课件的文字版(共 28 页,供检索与复制)

第1页:第十章文件导览

第十章文件章节封面,标示本章主线:C文件概述、文件类型指针、文件的打开与关闭、文件的读写、文件的定位与编程训练。

第2页:什么是输入输出

Introduction: What is I/O? 中央处理器与内存同显示器、网络、磁盘文件、键盘鼠标之间的数据传输,从内存写到外设为 Write(输出),读入内存为 Read(输入)。

第3页:文件的概念与使用目的

文件:存储在外部介质上数据的集合,是操作系统数据管理的单位,用文件名标识。

使用数据文件的目的:

  • 大量数据的输入/输出
  • 长期保存程序运行的中间数据或结果数据
  • 数据文件的改动不引起程序的改动——程序与数据分离
  • 不同程序可以访问同一数据文件中的数据——数据共享

第4页:文件的分类

文件的分类
分类依据类别说明
逻辑结构记录文件 / 流式文件由记录组成(定长与不定长)/ 由字符(字节)顺序组成
存储介质普通文件 / 设备文件磁盘磁带等存储介质 / 键盘显示器打印机等非存储介质
数据组织形式文本文件 / 二进制文件ASCII 文件每字节存放一个字符的 ASCII 码 / 按内存中存储形式原样存放

第5页:文本文件与二进制文件

以 int 型数 10000 为例:

  • 内存存储形式:0010011100010000(2 字节)
  • 二进制形式:0010011100010000
  • ASCII 形式:0011000100110000001100000011000000110000(5 字节,对应 '1' '0' '0' '0' '0')

文本文件特点:存储量大、速度慢、便于对字符操作;二进制文件特点:存储量小、速度快、便于存放中间结果。

第6页:文件处理方法

缓冲文件系统:高级文件系统,系统自动为正在使用的文件开辟内存缓冲区。

非缓冲文件系统:低级文件系统,由用户在程序中为每个文件设定缓冲区。

特点:减少读写次数,提高速度和数据管理质量。数据在内存与磁盘之间经输出缓冲区写出、经输入缓冲区读入。

第7页:文件结构体类型FILE

缓冲文件系统为每个正使用的文件在内存开辟文件信息区,文件信息用系统定义的名为 FILE 的结构体描述,FILE 定义在 stdio.h 中。

typedef struct { int fd; unsigned flags; int bsize; unsigned char *buffer; unsigned char *curp; } FILE;

第8页:文件类型指针

定义:FILE *fp;

用法:

  • 文件打开时,系统自动建立文件结构体,并把指向它的指针返回,程序通过这个指针获得文件信息、访问文件
  • 文件关闭后,它的文件结构体被释放

操作文件前应先定义 FILE 指针变量,C 程序通过它经操作系统访问磁盘文件。

第9页:文件操作步骤与标准设备文件

C 文件操作用库函数实现,包含在 stdio.h 中。

文件使用步骤:打开文件 → 文件读/写 → 关闭文件。

系统自动打开和关闭三个标准设备文件:

  • 标准输入——键盘 stdin
  • 标准输出——显示器 stdout
  • 标准出错输出——显示器 stderr

其余文件必须实施打开/关闭操作。

第10页:文件的打开fopen

函数原型:FILE *fopen(char *name, char *mode)

文件使用方式
方式含义
r / rb只读,为输入打开文本/二进制文件,文件不存在则打开失败
w / wb只写,为输出打开或建立文件,原内容被覆盖
a / ab追加,在文件尾追加数据
r+ / rb+读写,为读/写打开文件,文件不存在则失败
w+ / wb+读写,为读/写打开或建立文件,原内容被覆盖
a+ / ab+读写,打开或建立文件并在文件尾追加数据
FILE *fp; fp = fopen("c:\fengyi\bkc\test.dat", "r"); fp = fopen("aa.c", "w"); if (fp == NULL) { printf("File open error!\n"); exit(0); }

第11页:文件的关闭fclose

函数原型:int fclose(FILE *fp)

功能:关闭 fp 指向的文件,使文件指针变量与文件脱钩,释放文件结构体和文件指针。

返值:正常关闭返回 0,出错返回 EOF。

缓冲区中的内容在关闭时才真正写到磁盘,不关闭文件可能会丢失数据。

第12页:字符读写函数fputc与fgetc

文件 I/O 与终端 I/O的对应关系:

#define putchar(c) fputc(c, stdout) #define getchar() fgetc(stdin) #define putc(ch, fp) fputc(ch, fp) #define getc(fp) fgetc(fp)
  • int fputc(int c, FILE *fp):把字符 c 写入 fp 指向的文件,正常返回 c,出错返回 EOF
  • int fgetc(FILE *fp):从 fp 指向的文件读入一个字符,读到文件尾或出错返回 EOF

第13页:字符写入文件示例

#include <stdio.h> #include <process.h> void main() { FILE *fp; char ch, *filename = "out.txt"; if ((fp = fopen(filename, "w")) == NULL) { printf("cannot open file\n"); exit(0); } printf("Please input string:"); ch = getchar(); while (ch != '#') { fputc(ch, fp); putchar(ch); ch = getchar(); } fclose(fp); }

第14页:字符读取文件示例

ch = fgetc(fp); while (ch != EOF) { putchar(ch); ch = fgetc(fp); }

即以 (ch = fgetc(fp)) != EOF 作为循环条件判断文本文件是否结束,也可写成 fputc(ch, stdout); 输出。

第15页:判断二进制文件结束

while (!feof(fp)) { c = fgetc(fp); …….. }

函数原型:int feof(FILE *fp)

功能:判断文件是否结束,文件结束返回真(非零),未结束返回 0。

第16页:字符串读写函数fputs与fgets

  • int fputs(char *s, FILE *fp):向 fp 指向的文件写入字符串 s,正常返回写入的最后一个字符,出错返回 EOF
  • char *fgets(char *s, int n, FILE *fp):从 fp 指向的文件读入 n-1 个字符送入 s 指向的内存区并在最后加一个 '0',正常返回 s,出错或文件尾返回 NULL

说明:若读入 n-1 个字符前遇换行符或文件尾,即结束。

第17页:字符串读写示例

#include <stdio.h> #include <string.h> #include <process.h> void main() { FILE *fp; char string[81]; if ((fp = fopen("file.txt", "w")) == NULL) { printf("cann't open file"); exit(0); } while (strlen(gets(string)) > 0) { fputs(string, fp); fputs("\n", fp); } fclose(fp); if ((fp = fopen("file.txt", "r")) == NULL) { printf("cann't open file"); exit(0); } while (fgets(string, 81, fp) != NULL) fputs(string, stdout); fclose(fp); }

第18页:格式化读写函数

  • int fprintf(FILE *fp, "%…", var, …):按指定格式向 fp 指向的文件写入数据,正常返回写入数据个数,出错返回 EOF
  • int fscanf(FILE *fp, "%…", &var, …):按指定格式从 fp 指向的文件读入数据,正常返回读取数据个数,出错或文件尾返回 EOF
fprintf(fp, "%d,%6.2f", i, t); fscanf(fp, "%d,%f", &i, &t);

第19页:格式化读写示例

#include <stdio.h> #include <stdlib.h> void main() { char s[80], c[80]; int a, b; FILE *fp; if ((fp = fopen("test", "w")) == NULL) { puts("can't open file"); exit(0); } fscanf(stdin, "%s%d", s, &a); fprintf(fp, "%s %d", s, a); fclose(fp); if ((fp = fopen("test", "r")) == NULL) { puts("can't open file"); exit(0); } fscanf(fp, "%s%d", c, &b); fprintf(stdout, "%s %d\n", c, b); fclose(fp); }

第20页:数据块读写函数fread与fwrite

  • size_t fread(void *buffer, size_t size, size_t count, FILE *fp):从 fp 读入数据块,正常返回读入数据块数,出错或文件尾返回 0
  • size_t fwrite(void *buffer, size_t size, size_t count, FILE *fp):向 fp 写入数据块,正常返回写入数据块数,出错返回 0

参数:buffer 指向数据块首地址,size 为每个数据块的字节数,count 为数据块个数,fp 为文件指针。fread 与 fwrite 一般用于二进制文件的输入/输出。

第21页:数据块读写用法

float f[10]; FILE *fp; fp = fopen("aa.dat", "rb"); fread(f, 4, 10, fp); for (i = 0; i < 10; i++) fread(&f[i], 4, 1, fp); struct student { int num; char name[20]; char sex; int age; float score[3]; } stud[10]; for (i = 0; i < 10; i++) fread(&stud[i], sizeof(struct student), 1, fp);

第22页:学生数据转存示例

#include <stdio.h> #define SIZE 4 typedef struct student { char name[10]; int num; int age; char addr[15]; } STU; void main() { int i; STU stud[SIZE]; for (i = 0; i < SIZE; i++) scanf("%s%d%d%s", stud[i].name, &stud[i].num, &stud[i].age, stud[i].addr); save(stud); display(stud); } void save(STU stud[]) { FILE *fp; if ((fp = fopen("c:\stu_dat", "wb")) == NULL) { printf("cannot open file\n"); return; } for (int i = 0; i < SIZE; i++) if (fwrite(&stud[i], sizeof(struct student), 1, fp) != 1) printf("file write error\n"); fclose(fp); }

display 中以 rb 方式打开,逐个 fread 后按格式输出姓名、学号、年龄与地址。

第23页:文件位置指针概念

设文件 abc.txt 内容为 0 1 2 3 4 5 6 7 8 9 A B C D E F:

  • 执行 fp = fopen("abc.txt", "r"); 后位置指针指向开头
  • 调用一次 fgetc(fp); 后位置指针后移一个字符
  • 接着执行 fgets(str, 11, fp); 从当前位置继续读入

文件位置指针:指向当前读写位置的指针。

第24页:文件的顺序读写与rewind

函数原型:void rewind(FILE *fp),把 fp 指向的文件位置指针重置到文件首,无返回值。

文件读写方式

  • 顺序读写:位置指针按字节位置顺序移动
  • 随机读写:位置指针按需要移动到任意位置

如以 "w+" 方式打开文件,写入后用 rewind(fp); 即可从头读回刚才写入的内容。

第25页:fseek与ftell函数

int fseek(FILE *fp, long offset, int whence):改变文件位置指针,正常返回 0,出错返回非零。offset 为位移量(>0 向后、<0 向前移动),whence 为起始点:

起始点取值
起始点表示值
文件开始SEEK_SET0
文件当前位置SEEK_CUR1
文件末尾SEEK_END2
fseek(fp, 100L, 0); fseek(fp, 50L, 1); fseek(fp, -10L, 2);

long ftell(FILE *fp):返回位置指针当前位置(相对文件首的位移量),出错返回 -1L。

第26页:随机读取学生数据示例

#include <stdio.h> typedef struct student { char name[10]; int num; int age; char addr[15]; } STU; void main() { int i; STU stud[SIZE]; FILE *fp; if ((fp = fopen("c:\stu_dat", "rb")) == NULL) { printf("can't open file\n"); exit(0); } for (i = 0; i < SIZE; i += 2) { fseek(fp, i*sizeof(struct student), 0); fread(&stud[i], sizeof(struct student), 1, fp); printf("%-10s %4d %4d %-15s\n", stud[i].name, stud[i].num, stud[i].age, stud[i].addr); } fclose(fp); }

第27页:求文件长度示例

#include <stdio.h> void main() { FILE *fp; char filename[80]; long length; gets(filename); fp = fopen(filename, "rb"); if (fp == NULL) printf("file not found!\n"); else { fseek(fp, 0L, SEEK_END); length = ftell(fp); printf("Length of File is %ld bytes\n", length); fclose(fp); } }

第28页:本章小结

本章小结

  • 文件的概念
  • 文件处理方法——缓冲系统与非缓冲系统
  • 文件打开与关闭——fopen 与 fclose
  • 文件的读写操作:fputc 与 fgetc、fputs 与 fgets、fprintf 与 fscanf、fread 与 fwrite
  • 文件的定位——rewind、fseek、ftell
  • 文件的类型——文本文件、二进制文件
顶部目录