第十三章
文 件
第十二章 下次课讲
第十二章 位运算
一、概念,
前面介绍 c具有低级语言的特点,可以对内存单元地址及单元内容
中某一位,某几位进行操作。
位与字节,1byte=8bits int 2bytes
float 4bytes
char 1bytes
,,
,,
存储信息均按二进制,采用原码,反码,补码表示数。
若用二个字节表示 int, int a=5,b=-5;
十 进制 数 机器数 十进制数 机器数
5 原码,0000000000000101 -5 原码,1000000000000101
5 反码,0000000000000101 -5 反码,1111111111111010
5 补码,0000000000000101 -5 补码,1111111111111011
二,位运算符,
位操作是指按位运算(与逻辑运算 !,&&,|| 不同)
运算符 含义 举例
& 按位与操作 0&1=0,1&0=0,0&0=0,1&1=1
| 按位或操作 0 | 1 =1,1 | 0=1,0 | 0=0,1 | 1=1
^ 按位异或操作 0 ^ 1=1,1^ 0=1,0^ 0=0,1^ 1=0
~ 按位取反操作 ~0=1,~1=0
<< 左移 00000010<<2,结果, 00001000
(不产生溢出,可实现左移一位,乘 2)
>> 右移 01000000>>2,结果, 00010000
(不产生溢出,可实现右移一位,除 2)
复合位运算, &=,| =,^=,~ =,<<=,>>=
三、应用举例,
1,按位与,实时控制的需要,仅对 a(整型数)
中某几位取出进行监测,而对 a中其他位屏蔽掉。可
以根据需要设置屏蔽字(关心的某几位置 1,不关心
位置 0)。 a和屏蔽字相与,即可。
a=0110 1101 1001 1010 保留 a的低 7位
mask=0000 0000 0111 1111 mask的低 7位置 1,其它置 0
a&mask=0000 0000 0001 1010 取出 a低 7位的原状态
2,按位或,实时控制的需要,常须送出去的控制信号,
某几位为 1(将某些开关合上)可以根据需要,控制字的某几位置
1,再与 a相或。
a=0110 1101 1001 1000 将 a的低 4位置 1
cont=0000 0000 0000 1111 cont的低四位置 1
a |cont=0110 1101 1001 1111 使 a的低 4位为 1,其它位为
原状态
3,按位异或操作,根据需要将 a中某几位取反,这
时 cont相应位置 1,再与 a异或,即可。
a=0110 1101 1011 0111 将 a的低 8位取反
cont=0000 0000 1111 1111 cont的低 8位置 1
a^cont=0110 1101 0100 1000 取 a低 8位的反,其
它位不变
还可实现加、解密功能,将 a异或一个 key(自定)得
到 a’(加密后的码)再用 a’ 异或 key(与加密时用的 key
相同)得到原 a,
a= 0001 1011
key= 0000 0101
a’=a^key= 0001 1110
a’ = 0001 1110
key= 0000 0101
a= a’^key= 0001 1011
第十章 文件
一,C 文件的概述
1、什么是文件? 我们所说的文件是存储在磁盘上的
数据集合,也就是我们说的数据文件。
2、文件用来保存什么数据? 可以保存程序中使用的
数据,比如学生成绩单,也可以保存程序的运行结果,
不如对成绩单的排序、程序计算出的一组数据等。
3,C语言文件的组成, C语言文件是以字符(字节)
为单位存储的,也就是每一个 C语言文件都是一个字
符序列,C语言文件分两种存储方式。
一种是 文本( ASCII码)文件,文件中每一个字
节存放一个字符。
另一种是 二进制文件,是把内存中的二进制数直
接存储到磁盘文件中。
如 int型数 10000
0010011100010000
内存存储形式
0010011100010000
二进制形式
0011000100110000001100000011000000110000
ASCII形式
文本文件特点,
存储量大、速度慢、便于对字符操作
二进制文件特点,
存储量小、速度快、便于存放中间结果
两种存储方式的比较
磁盘文件
输出文件缓冲区
输入文件缓冲区
程序数据区
a
缓冲文件系统,
4、什么是缓冲文件系统?
二,文件类型指针
1、什么是文件结构体 FILE?
1)缓冲文件系统为每个正使用的文件在内存开辟文件
信息区
2)文件信息用系统定义的名为 FILE的结构体描述
3) FILE定义在 stdio.h中
typedef struct
{ int _fd; //文件号
int _cleft; //缓冲区中剩下的字符数
int _mode; //文件操作方式
char *_next; //文件当前读写位置
char *_buff; //文件缓冲区位置
}FILE;
用 typedef 定义类型
例如,
typedef int INTEGER;
typedef float REAL;
main()
{INTEGER a,b;
REAL f;
….,
}
2、文件类型指针
1)指针变量说明,FILE *fp;
用法,
?文件打开 时,系统 自动 建立文件结构
体,并把指向它的指针返回来,程序
通过这个指针获得 文件信息,访问文件
?文件关闭 后,它的文件结构体被释放
三,文件的打开与关闭
1、什么是打开文件?
文件在操作之前必须打开,所谓打开文件指的是:通
过一个库函数(包含在 stdio.h里)的操作,向编译
系统指出要操作的 文件名、对文件的操作方式(读
或写)、确定指向该文件的指针变量。
2、如何打开一个文件?
打开文件用 fopen函数
?功能:按指定方式打开文件
?返值:正常打开,返回指向文件结构体的指针;打开失
败,返回 NULL ( 0)
调用方式通常为,FILE *fp;
fp=fopen(文件名,使用文件方式 )
FILE *fp;
fp= fopen (“c:\\fengyi\\bkc\\test.dat”,”r”);
例如,
FILE *fp;
char *filename=“c:\\fengyi\\bkc\\test.txt”
fp= fopen(filename,”w”);
文件打开与测试
FILE *fp;
fp=fopen(“aa.dat”,“w”);
if(fp==NULL)
{ printf(“File open error!\n”);
exit(0);
}
“r+/rb+” (读写 )
“a/ab” (追加 )
“w/wb” (只写 )
“r/rb” (只读 )
“w+/wb+” (读写 )
“a+/ab+” (读写 )
为 输入 打开一个文本 /二进制文件
为 输出 打开或建立一个文本 /二进制文件
为读 /写打开一个文本 /二进制文件
为读 /写建立一个文本 /二进制文件
为读 /写打开或建立一个文本 /二进制文件
向文本 /二进制文件尾 追加 数据
文件使用方式 含义
3、文件打开方式,
4、三个特殊的文件
系统 自动 打开和关闭三个 标准文件,
标准输入 ------键盘 stdin
标准输出 ------显示器 stdout
标准出错输出 -----显示器 stderr
磁盘文件
输出文件缓冲区
输入文件缓冲区
程序数据区
a
缓冲文件系统,不关闭文件可能会 丢失数据
fclose
5、为什么需要关闭文件?
6、如何关闭文件?
文件关闭使用 fclose函数
?功能:关闭 fp指向的文件
?返值:正常关闭返回 0;出错时,返回非 0
函数调用的一般形式为,
fclose(文件指针 );
例如,fclose(fp);
四,文件的读写
1、以字符为单位读 / 写文件
使用函数 fputc (putc) 与 fgetc (getc)
1) fputc函数 (写文件)
?函数调用的一般格式为, fputc(ch,fp)
?功能:把一个字符( ch)写入 fp指向的文件中
?返值:正常,返回 ch ;出错,为 EOF ( -1)
2) fgetc函数 (读文件)
?函数调用的一般格式为, ch=fgetc(fp);
?功能:从 fp指向的文件中读取 一 个字符,赋给 ch 。
?返值:正常,返回读到的代码值 ;读到文件尾或出错,为
EOF
例 1,从键盘输入字符,
逐个存到磁盘文件中,
直到输入‘ #“为止,在
显示器上同时显示出来。
运行情况,
computer and c# 输入
copmputer and c 输出
#include <stdio.h>
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);
}
#include <stdio.h>
main()
{ FILE *fp;
char ch,*filename=“out.txt”;
if((fp=fopen(filename,”r"))==NULL)
{ printf("cannot open file\n");
exit(0);
}
while((ch=fgetc(fp))!=EOF)
putchar(ch);
fclose(fp); 判断文本文件
} 是否结束
例 2,读文本文件的内
容,并显示出来。
判断读文件时是否读到结尾(文件结束)的方法,
如果是文本文件可以用 EOF识别,例如
while((ch=fgetc(fp))!=EOF)
如果是二进制文件可以使用函数 feof 识别,例如
while(!feof(fp))
函数 feof的功能和使用方式
函数调用,feof(fp);
功能:判断文件是否结束
返值:文件结束,返回真(非 0
);文件未结束,返回 0
feof也
适合文
本文件
例 3 文件拷贝 #include <stdio.h> main()
{ FILE *in,*out;
char ch,infile[10],outfile[10];
scanf("%s",infile);
scanf("%s",outfile);
if ((in = fopen(infile,"r"))== NULL)
{ printf("Cannot open infile.\n");
exit(0);
}
if ((out = fopen(outfile,"w"))== NULL)
{ printf("Cannot open outfile.\n");
exit(0);
}
while (!feof(in))
fputc(fgetc(in),out);
fclose(in); fclose(out);
}
2、以数据块为单位读 /写文件
使用函数 fread 与 fwrite
1) fread函数 (读文件)
调用的一般形式为,
fread(buffer,size count,fp);
说明,
?buffer,指向要输入数据块的首地址的指针
?size,每个要读的数据块的大小(字节数)
?count,要读的数据块的个数
?fp,要读文件指针
功能:读数据块
返值:成功,返回读的块数 (count);出错或文
件尾,返回 0
2) fwrite函数 (写文件)
调用的一般形式为,
fwrite(buffer,size,count,fp);
buffer,指向要输出数据块的首地址的指针
size,每个要写的数据块的大小(字节数)
count,要写的数据块的个数
fp,要写的文件指针
功能:写数据块
返值:成功,返回写的块数( count);出
错或文件尾,返回 0
读函数 fread 与 写函数 fwrite 通常用于二进制文件。
例 float f[2];
FILE *fp;
fp=fopen(“aa.dat”,“rb”);
fread(f,4,2,fp);
for(i=0;i<2;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);
for(i=0;i<2;i++)
fwrite(&f[i],4,1,fp);
例如:从键盘输入 4个学生数据,把他们转存到
磁盘文件中去
#include <stdio.h>
#define SIZE 4
struct student_type
{ char name[10];
int num;
int age;
char addr[15];
}stud[SIZE];
main()
{ int i;
for(i=0;i<SIZE;i++)
scanf("%s%d%d%s",stud[i].name,&stud[i].num,
&stud[i].age,stud[i].addr);
save();
display();
}
void save()
{ FILE *fp;
int i;
if((fp=fopen("d:\fengyi\exe\stu_dat","wb"))==NULL)
{ printf("cannot open file\n");
return;
}
for(i=0;i<SIZE;i++)
if(fwrite(&stud[i],sizeof(struct student_type),1,fp)!=1)
printf("file write error\n");
fclose(fp);
}
void display()
{ FILE *fp;
int i;
if((fp=fopen("d:\fengyi\exe\stu_dat","rb"))==NULL)
{ printf("cannot open file\n");
return;
}
for(i=0;i<SIZE;i++)
{ fread(&stud[i],sizeof(struct student_type),1,fp);
printf("%-10s %4d %4d %-15s\n",stud[i].name,
stud[i].num,stud[i].age,stud[i].addr);
}
fclose(fp);
}
3、采用格式方式读 /写文件
使用函数 fprintf与 fscanf
?函数调用的一般方式为,
fprintf(文件指针,格式字符串,输出表列 ) (写)
fscanf(文件指针,格式字符串,输入表列 ) (读)
?功能:按格式对文件进行读 /写操作
?返值:成功,返回读 /写的个数 ;出错或文件尾,返回 EOF

fprintf(fp,“%d,%6.2f”,i,t); //将 i和 t按 %d,%6.2f格式输出到 fp文件
fscanf(fp,“%d,%f”,&i,&t); //若文件中有 3,4.5,则将 3送入 i,4.5送入 t
#include <stdio.h>
main()
{ char s[80],c[80];
int a,b;
FILE *fp;
if((fp=fopen("test","w"))==NULL)
{ puts("can't open file"); exit() ; }
fscanf(stdin,"%s%d",s,&a); /*read from keaboard*/
fprintf(fp,"%s %d",s,a); /*write to file*/
fclose(fp);
if((fp=fopen("test","r"))==NULL)
{ puts("can't open file"); exit(); }
fscanf(fp,"%s%d",c,&b); /*read from file*/
fprintf(stdout,"%s %d",c,b); /*print to screen*/
fclose(fp);
}
例 从键盘按格式输入数据存到磁盘文件中去
4、以字符串为单位读 /写文件
使用函数 fgets 与 fputs
?函数调用一般形式,
fgets(str,n,fp); (读 )
fputs(str,fp); (写)
?功能:从 fp指向的文件读 /写一个字符串
?返值,
?fgets正常时返回读取字符串的首地址;出错或
文件尾,返回 NULL
?fputs正常时返回写入的最后一个字符;出错为
EOF
fputs把 str指向的字符串写入 fp指向的文件
fgets从 fp所指文件读 n-1个字符送入 str指向的内存区,
并在最后加一个 ‘ \0’
(若读入 n-1个字符前遇换行符或文件尾( EOF) 即结束 )
五、文件的定位
1、什么是文件位置指针?指向当前读写位置的指针
2、文件的 读写方式
顺序读写:位置指针按字节位置顺序移动,叫 ~
随机读写:位置指针按需要移动到任意位置,叫 ~
3、几个文件位置指针定位函数
?rewind函数
? 函数调用形式, rewind(文件指针 );
?功能:重置文件位置指针到文件开头
?返值:无
#include <stdio.h>
main()
{ FILE *fp1,*fp2;
fp1=fopen("d:\fengyi\bkc\file1.c","r");
fp2=fopen("d:\fengyi\bkc\file2.c","w");
while(!feof(fp1)) putchar(getc(fp1));
rewind(fp1);
while(!feof(fp1)) putc(getc(fp1),fp2);
fclose(fp1);
fclose(fp2);
}
例 对一个磁盘文件进行显示和复制两次操作
?fseek函数
?函数的调用形式,fseek(文件指针,位移量,起始点 );
?功能:改变文件位置指针的位置
?返值:成功,返回 0;失败,返回非 0值
文件指针 位移量(以起始点为基点,移动的字节数 )
>0 向后移动
<0 向前移动
起始点
文件开始 SEEK_SET 0
文件当前位置 SEEK_CUR 1
文件末尾 SEEK_END 2
例 fseek(fp,100L,0); 将指针移到离文件头 100字节处
fseek(fp,50L,1);将指针移到离当前位置 50个字节处
fseek(fp,-10L,2);将指针从文件尾处后退 10个字节处
?ftell函数
?函数调用形式,ftell(fp);
?功能:返回位置指针当前位置 (用相对文件开头的位移
量表示 )
?返值:成功,返回当前位置指针位置;失败,返回 -1L,
例 磁盘文件上有 10个学生数据,
要求读入第 1,3,5,7,9个学生数据
并显示
main() 29B
{ int i; 29B
FILE *fp; 29B
if((fp=fopen("studat","rb"))==NULL) 29B
{ printf("can't open file\n");exit(0); } 29B
for(i=0;i<10;i+=2) 29B
{fseek(fp,i*sizeof(struct student_type),0); 29B
fread(&stud[i],sizeof(struct student_type),1,fp); 29B
printf("%s %d %d %s\n",29B
stud[i].name,stud[i].num,stud[i].age,stud[i].addr); 29B
}
fclose(fp);
}
#include <stdio.h>
struct student_type
{ int num;
char name[10];
int age;
char addr[15];
}stud[10];
例 求文件长度 (ch12_101.c)
#include"stdio.h"
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 %1d bytes\n",length);
fclose(fp);
}
}
六,出错的检测
?ferror函数
?函数调用形式,ferror(fp);
?功能:测试文件是否出现错误
?返值:未出错,0;出错,非 0
?说明
?每次调用文件输入输出函数,均产生一个新
的 ferror函数值,所以应及时测试
?fopen打开文件时,ferror函数初值自动置为 0
?clearerr函数
?函数调用形式,clearerr(fp);
?功能:使文件错误标志置为 0
?返值:无
?说明:出错后,错误标志一直保留,直
到对同一文件调 clearerr(fp)或 rewind或任
何其它一个输入输出函数
练习,
1、若在 fopen函数中使用文件的方式是 "wb+",该方
式的含义是 ( )
(A) 为读 /写打开一个文本文件
(B) 为输出打开一个文本文件
(C) 为读 /写建立一个新的文本文件
(D) 为读 /写建立一个新的二进制文件
2,C语言中系统的标准输入文件( stdin)是指 ( )
(A)键盘 (B)显示器 (C)软盘 (D)硬盘
3、下述关于 C语言文件操作的结论中,( )是正确的
(A) 对文件操作必须是先关闭文件
(B) 对文件操作必须是先打开文件
(C) 对文件操作顺序无要求
(D) 对文件操作前必须先测试文件是否存在,然后
再打开文件
4,C语言可以处理的文件类型是 ( )
(A) 文本文件和数据文件 (B)文本文件和二进制文件
(C) 数据文件和二进制文件 (D) 数据代码文件
5、对 C语言的文件存取方式中,文件 ( )
(A) 只能顺序存取
(B) 只能随机存取(也称直接存取)
(C) 可以是顺序存取,也可以是随机存取
(D) 只能从文件的开头存取
6、函数调用语句 fseek(fp,-10L,2);的含义是 ( )
(A)将文件位置指针移动距离文件头 10个字节处
(B)将文件位置指针从当前位置向文件尾方向移动 10个字节
(C)将文件位置指针从当前位置向文件头方向移动 10个字节
(D)将文件位置指针从文件未尾处向文件头方向移动 10个字节