You are on page 1of 20

高级语言程序设计

主讲人:袁学松
N e w H o r i z o n C o l l e g e E n g l i s h Book 3

VI. Answers To Exercises Unit 5

上一讲回顾
结构体定义
结构体与数组
结构体与指针
用 typedef 定义类型

2
N e w H o r i z o n C o l l e g e E n g l i s h Book 3

VI. Answers To Exercises Unit 5

第十讲 编译预处理与文件
 宏定义
 “ 文件包含”处理
 C 文件概述
 文件类型指针
 文件的打开与关闭
 文件的读写

3
N e w H o r i z o n C o l l e g e E n g l i s h Book 3

VI. Answers To Exercises Unit 5

编译预处理
作用:对源程序编译之前做一些处理 , 生成扩展 C
源程序
种类
• 宏定义 #define
• 文件包含 #include
• 条件编译 #if--#else--#endif 等
格式:
• “#” 开头
• 占单独书写行
• 语句尾不加分号
4
N e w H o r i z o n C o l l e g e E n g l i s h Book 3

VI. Answers
§ 10.1 宏定义To Exercises 宏体可缺省 , 表示宏名 Unit 5
定义过或取消宏体
• 一般形式: #define 宏名 [ 宏体 ]
• 功能 : 用指定标识符 ( 宏名 ) 代替字符序列 ( 宏体 )

例 #define YES 1
如 例 #define main()
• 定义位置 : 任意 ( YES
#define WIDTH
一般在函数外面 1 80 )
#define
#define NO { ……..
LENGTH 0 ( WIDTH+40 ) YES 原作用域
• 作用域#define
: var=LENGTH*2;
从定义命令到文件结束
PI } 3.1415926
#define ( #undef
OUT YES
printf(“Hello,World”);
• #undef 可终止宏名作用域
宏展开: var= 80+40
) *2;
例 #define WIDTH #define 80 YES 0
格式: #undef
#define LENGTH
宏名
max() WIDTH+40
YES 新作用域
• 宏展开:预编译时
var=LENGTH*2; , 用宏体替换宏名
{…….. --- 不作语法检
•如查
引号中的内容与宏名相同也不置换 } *2;
宏展开: var= if(x==YES)
80+40 printf(“correct!\n”);
例 else if (x==NO)
#define
• 宏定义可嵌套,不能递归 PI 3.14159printf(“error!\n”);
展开后: printf(“2*PI=%f\n”,PI*2);
if(x==1) printf(“correct!\n”);
•例 宏展开: else printf(“2*PI=%f\
宏定义中使用必要的括号()if (x==0) printf(“error!\n”);
#define MAX MAX+10 ()
n”,3.14159*2);
5
N e w H o r i z o n C o l l e g e E n g l i s h Book 3

VI. Answers To <>


Exercises
直接按标准目录搜索 Unit 5
“” 先在当前目录搜索,再搜索标准目录
§ 10.2 文件包含可指定路径
 功能:一个源文件可将另一个源文件的内容全部包含进来
 一般形式: #include < 文件名 >
或 #include “ 文件名”
 处理过程:预编译时 , 用被包含文件的内容取代该预处
理命令,再对“包含”后的文件作一个源文件编译

#include “file2.c” file2.c


B
A A
file2.c
file1.c file1.c
6
N e w H o r i z o n C o l l e g e E n g l i s h Book 3

VI. Answers To Exercises Unit 5

 被包含文件内容
file3.c
• 源文件 (*.c) 宏定义
• 头文件 (*.h) 数据结构定义 file2.c
函数说明等 file1.c
 文件包含可嵌套 A

#include “file2.c” #include “file3.c”


C

A B
file3.c
file1.c file2.c

7
N e w H o r i z o n C o l l e g e E n g l i s h Book 3

VI. Answers To Exercises Unit 5

§ 10.3 C 文件概述
 文件:存储在外部介质上数据的集合 , 是操作系
统数据管理的单位
 文件分类
使用数据文件的目的
1 、数据文件的改动不引起程序的改动——程序与数据分离
• 按文件的逻辑结构:
2 、不同程序可以访问同一数据文件中的数据——数据共享
– 记录文件:由具有一定结构的记录组成(定长和不定长)
3 、能长期保存程序运行的中间数据或结果数据
– 流式文件:由一个个字符(字节)数据顺序组成
• 按存储介质:
– 普通文件:存储介质文件(磁盘、光盘等)
– 设备文件:非存储介质(键盘、显示器、打印机等)
• 按数据的组织形式:
– 文本文件: ASCII 文件,每个字节存放一个字符的 ASCII

8
– 二进制文件:数据按其在内存中的存储形式原样存放
N e w H o r i z o n C o l l e g e E n g l i s h Book 3

VI. Answers To Exercises Unit 5

 文件处理方法
• 缓冲文件系统:系统自动为正在使用的文件开辟内存
缓冲区

输入文件缓冲区
缓冲文件系统: 磁盘
程序数据区
a

输出文件缓冲区

9
N e w H o r i z o n C o l l e g e E n g l i s h Book 3

VI. Answers To Exercises Unit 5

§ 10.4 文件类型指针
 文件结构体 FILE
• 缓冲文件系统为每个正使用的文件在内存开辟文件信
息区
• 文件信息用系统定义的名为 FILE 的结构体描述
• FILE 定义在 stdio.h 中
typedef struct
{ short level;
unsigned flags;
char fd;
unsigned char hold;

}FILE;
10
N e w H o r i z o n C o l l e g e E n g l i s h Book 3

VI. Answers To Exercises Unit 5

文件类型指针
•指针变量说明: FILE *fp;
•用法:
–文件打开时,系统自动建立文件结构体,并把指向它
的指针返回来,程序通过这个指针获得文件信息 , 访问文

–文件关闭后,它的文件结构体被释放
文件名
文件使用
C 程序 方式 操作系统

文件类型指针

磁盘 11
N e w H o r i z o n C o l l e g e E n g l i s h Book 3

VI. Answers To Exercises Unit 5

§ 10.5 文件的打开与关闭
C 文件操作用库函数实现 , 包含在 stdio.h
例 文件打开与测试
文件使用方式
文件使用方式 : 打开文件
FILE *fp; -->
含义文件读 / 写 --> 关闭文件
 系统自动打开和关闭三个标准文件:
“r/rb” ( 只读 ) fp=fopen(“aa.c”,“w”);
为输入打开一个文本 / 二进制文件
• 标准输入
“w/wb” if(fp==NULL)
( 只写 )------ 键盘 stdin
为输出打开或建立一个文本 / 二进制文件
例 FILE { *fp;
printf(“File open error!\n”);
• 标准输出
例( 追加
“a/ab” FILE
------*fp;
)char 显示器 stdout
*filename=“c:\VC\test.dat”
向文本 / 二进制文件尾追加数据
exit(0);
• 标准出错输出 fp=
“r+/rb+” ( 读写fp=
fopen (“c:\VC\test.dat”,”r”);
) fopen(filename,”r”);
为读 / 写打开一个文本 / 二进制文件stderr
}
“w+/wb+”
打开文件 fopen 为读 / 写建立一个文本 / 二进制文件
( 读写 ) 使用文件方式
• 函数原型: FILE *fopen(char *name,char *mode)
“a+/ab+” ( 读写 ) 为读 / 写打开或建立一个文本 / 二进制文件

• 功能:按指定方式打开文件
要打开的文件名
• 返值:正常打开,为指向文件结构体的指针;打
开失败,为 NULL(0) 12
N e w H o r i z o n C o l l e g e E n g l i s h Book 3

VI. Answers To Exercises Unit 5

 文件关闭 fclose
• 作用 : 使文件指针变量与文件“脱钩”,释放文件结构
体和文件指针
• 函数原型: int fclose(FILE *fp)
• 功能:关闭 fp 指向的文件
• 返值:正常关闭为 0; 出错时 ,EOF(-1)
缓冲文件系统:
输入文件缓冲区
磁盘文件
程序数据区
a

输出文件缓冲区 fclose 13
N e w H o r i z o n C o l l e g e E n g l i s h Book 3

VI. Answers To Exercises Unit 5

§ 10.6 文件的读写
 字符 I/O:fputc 与 fgetc
• fputc
– 函数原型: int fputc(char c, FILE *fp)
– 功能:把一字节代码 c 写入 fp 指向的文件中
– 返值:正常,返回 c; 出错,为 EOF ( -1 )
• fgetc
– 函数原型: int fgetc(FILE *fp)
– 功能:从 fp 指向的文件中读取一字节代码
– 返值:正常,返回读到的代码值 ; 读到文件尾或出错,为
EOF
文件 I/O 与终端 I/O
#define putchar( c ) fputc(c,stdout)
#define getchar( ) fgetc(stdin) 14
N e w H o r i z o n C o l l e g e E n g l i s h Book 3

VI. Answers To Exercises Unit 5

#include <stdio.h>
main()
例 12.1 从键盘输入字
{ FILE *fp;
符,逐个存到磁盘文件
char ch,*filename="out.txt";
中,直到输入‘ #“ 为
fp=fopen(filename,"w");

printf("Please input string:");
ch=getchar();
while(ch!='#')
{ fputc(ch,fp);
putchar(ch);
ch=getchar();
}
fclose(fp);
}
15
N e w H o r i z o n C o l l e g e E n g l i s h Book 3

VI. Answers To Exercises Unit 5

例 12.2 读文本文件内容,并显示
#include <stdio.h>
main()
{ FILE *fp;
char ch, filename[20];
gets(filename);
fp=fopen(filename, "r" );
while((ch=fgetc(fp))!=EOF)
putchar(ch);
fclose(fp);
判断文本文件是否结束
}

16
N e w H o r i z o n C o l l e g e E n g l i s h Book 3

VI. Answers To Exercises Unit 5

 格式化 I/O:fprintf 与 fscanf


• 函数原型:
int fprintf(FILE *fp,const char *format[,argument,…])
int fscanf(FILE *fp,const char *format[,address,…])
• 功能:按格式对文件进行 I/O 操作
• 返值:成功 , 返回 I/O 的个数 ; 出错或文件尾 , 返回
例 fprintf(fp,“%d,%6.2f”,i,t);
EOF
// 将 i 和 t 按 %d,%6.2f 格式输出到 fp 文

fscanf(fp,“%d,%f”,&i,&t);
// 若文件中有 3,4.5 , 则将 3 送入 i, 4.5 送
入t

17
N e w H o r i z o n C o l l e g e E n g l i s h Book 3

VI.例Answers
12.3 从键盘按格式输入数据存到磁盘文件中去
To Exercises Unit 5

#include <stdio.h>
int main()
{ char s[80],c[80];
int a,b;
FILE *fp;
fp=fopen("test.txt","w");
fscanf(stdin,"%s %d",s,&a);/*read from keyboard*/
fprintf(fp,“%s %d",s,a);/*write to file*/
fclose(fp);
fp=fopen("test.txt","r");
fscanf(fp,"%s%d",c,&b);/*read from file*/
fprintf(stdout,"%s,%d",c,b);/*print to screen*/
fclose(fp);
}
18
N e w H o r i z o n C o l l e g e E n g l i s h Book 3

VI. Answers To Exercises Unit 5

 字符串 I/O: fgets 与 fputs


• 函数原型: char *fgets(char *s,int n,FILE *fp)
int fputs(char *s,FILE *fp)
• 功能:从 fp 指向的文件读 / 写一个字符串
• 返值:fputs 把 s 指向的字符串写入 fp 指向的文件
fgets 从 fp 所指文件读 n-1 个字符送入 s 指向的内存区 ,
– fgets 正常时返回读取字符串的首地址;出错或文件
并在最后加一个‘ \0’
( 若读入 尾,返回 NULL
n-1 个字符前遇文件尾( EOF )即结束 )
– fputs 正常时返回写入的最后一个字符;出错为 EOF

19
N e w H o r i z o n C o l l e g e E n g l i s h Book 3

VI. Answers To Exercises


#include<stdio.h> Unit 5
#include<string.h>
例 12.4 从键盘读入 int main()
字符串存入文件, { FILE *fp;
再从文件读回显示 char string[81];
fp=fopen("file.txt","w");
while(strlen(gets(string))>0)
{ fputs(string,fp);
fputs("\n",fp);
}
fclose(fp);
fp=fopen("file.txt","r");
while(fgets(string,81,fp)!=NULL)
fputs(string,stdout);
fclose(fp);
}
20

You might also like