模块7-位运算与文件_第1页
模块7-位运算与文件_第2页
模块7-位运算与文件_第3页
模块7-位运算与文件_第4页
模块7-位运算与文件_第5页
已阅读5页,还剩115页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1

C语言程序设计任务式教程(微课版)

VisualC++2计算机工程学院模块7位运算与文件

任务1位运算任务2文件

3计算机工程学院任务1位运算学习目标掌握六种位运算的运算符与格式、运算规则。n位n位图7-1二进制的循环移位图解4计算机工程学院案例1二进制的循环移位1.问题描述

实现二进制的循环移位。设待移位的数为a,移位情况如图示,假设系统中2个字节存放一个整数。

7.1.1案例讲解

Before:00000000000000011Leftbitsmove1result:Binary:0000000000000010Hex:21Rightbitsmove1result:Binary:1000000000000000Hex:80002Leftbitsmove1result:Binary:0000000000000100Hex:42Rightbitsmove1result:Binary:0000000000000001Hex:12.编程分析

该问题的要求,在于将待移位数a分成两部分,然后交换这两部分的位置。从而可知,需要增加两个变量来存储变量a的两部分的值,而这些操作都需要求助于位运算。程序描述如下:5计算机工程学院voidmain(){定义无符号整型变量a,b,c定义整型变量n输入待移动数a和所移动位数n对数a左移16-n位后的结果给变量b对数a右移n位后的结果给变量c对变量b,c做按位或运算,计算结果给变量c输出变量a和c}n位n位图7-1二进制的循环移位图解6计算机工程学院3.编写源程序/*EX7_1.CPP*/#include<stdio.h>voidmain(){unsignedshortunsignedA,unsignedB,unsignedC;intintN;printf("请输入一个无符号整型变量unsignedA的值:");scanf("%u",&unsignedA);printf("请输入移位位数intN的值:");7计算机工程学院

scanf("%d",&intN);unsignedB=unsignedA<<(16–intN);unsignedC=unsignedA>>intN;unsignedC=unsignedC|unsignedB;printf("unsignedA的值:%o\n",unsignedA);printf("unsignedC的值:%o\n",unsignedC);}4.运行结果8计算机工程学院图7-2案例1运行结果5.归纳分析在本案例中,使用了左移位运算、右移位运算和按位或运算相配合,实现二进制的循环移位。9计算机工程学院该程序运行的一个实例,输入unsignedA的值为174,移动位数intN的值为2,则运行结果如图。其中:十进制数174(即为八进制数256)的二进制数为0000000010101110(按题设要求为2个字节),循环移动2位,则循环移位后的二进制结果为1000000000101011(即为八进制数100053)。A:0000000010101110(AE174)循环移动2位:1000000000101011(802B)10计算机工程学院

7.1.2基础理论

C语言中提供给开发人员一种位的运算,这种位的运算常用在检测和控制领域中,这和C语言的特性关系非常大,因为C语言是具有高级语言的特点和低级语言的功能,能完成一些汇编语言所能完成的功能。给开发人员提供了一定的简便。C语言提供了六种位运算,下面分别介绍。1.按位与运算(&)

(1)格式:x&y(2)规则:按位与运算符“&”是双目运算符。其功能是参加运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1,11计算机工程学院否则为0。参加运算的数以补码方式出现。例如:9&5可写算式如下

00001001

&0000010100000001结果为:9&5=1。(3)主要用途:用来对某些位清0或保留某些位。例如:把a的高八位清0,保留低八位,可作a&255运算(255的二进制数为0000000011111111)。12计算机工程学院2.按位或运算符(|)(1)格式:x|y(2)规则:按位或运算符“|”是双目运算符。其功能是参加运算的两数各对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就为1。参加运算的两个数均以补码出现。例如:9|5可写算式如下

00001001

|0000010100001101结果为:9|5=1313计算机工程学院

(3)主要用途:常用来将源操作数某些位置1,其他位不变。例如:把a的低八位置1,保留高八位,可作a|255运算(255的二进制数为0000000011111111)。3.按位异或运算(^)

(1)格式:x^y(2)规则:按位异或运算符“^”是双目运算符。其功能是参加运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。参加运算数仍以补码出现。例如:9^5可写成算式如下14计算机工程学院

00001001

^0000010100001100

结果为:9^5=12

(3)主要用途:常用来将源操作数某些特定位的值取反,其他位不变。

例如:把a的低八位取反,保留高八位,可作a^255

运算(255

的二进制数为0000000011111111)。15计算机工程学院4.求反运算(~)

(1)格式:~x(2)规则:求反运算符~为单目运算符,具备右结合性。其功能是对参加运算的数的各二进位按位求反。例如:~9可写成算式如下

~00000000000010011111111111110110结果为:~9=-1016计算机工程学院5.左移运算(<<)(1)格式:x<<位数(2)规则:左移运算符“<<”是双目运算符。其功能是把“<<”左边的运算数的各二进位全部左移若干位,“<<”右边的数指定移动的位数。低位补0,高位溢出。例如:设a=15,a<<2表示把000001111左移为00111100(十进制60)。17计算机工程学院6.位右移(>>)(1)格式:x>>位数(2)规则:使操作数的各位右移,高位补0,低位溢出。例如:5>>2=100000101右移两位

0000000118计算机工程学院

7.1.3技能训练

【实验7-1】运行下面的程序,分析运行结果。

/*EX7_2.CPP*/#include<stdio.h>voidmain(){intintA=0x36,intB=0xc0,intC;intC=intA&intB;printf("intA=%x\nintB=%x\nintC=%x\n",intA,intB,intC);}19计算机工程学院该程序利用按位与运算,把变量a的所有位清0。运行结果如图7-3所示。图7-3程序EX7_2运行结果20计算机工程学院【实验7-2】运行下面的程序,分析运行结果。

/*EX7_3.CPP*/#include<stdio.h>voidmain(){intintA,intB=255,intC;scanf("%d",&intA);intC=intA&intB;printf("intA=%x\nintB=%x\nintC=%x\n",intA,intB,intC);}21计算机工程学院该程序利用按位与运算,把变量a的高八位清0,保留低八位。假设输入变量intA的值为:12345,则运行结果如图7-4。图7-4程序EX7_3运行结果22计算机工程学院【实验7-3】运行下面的程序,分析运行结果:

/*EX7_4.CPP*/#include<stdio.h>voidmain(){intintA=9,intB=1,intC;intC=intA&intB;printf("intA=%xintB=%xintC=%x\n",intA,intB,intC);}23计算机工程学院该程序利用按位与运算,把变量intA的最低位取出。运行结果如图7-5。图7-5程序EX7_4运行结果24计算机工程学院【实验7-4】运行下面的程序,分析运行结果:

/*EX7_5.CPP*/#include<stdio.h>voidmain(){intintA,intB=31,intC;scanf("%d",&intA);intC=intA|intB;printf("intA=%xintB=%xintC=%x\n",intA,intB,intC);}25计算机工程学院该程序利用按位或运算,将变量intA的低5位置为1。假设输入变量intA的值为:6,则运行结果如图7-6。图7-6程序EX7_5运行结果26计算机工程学院【实验7-5】运行下面的程序,分析运行结果:

/*EX7_6.CPP*/#include<stdio.h>voidmain(){intintA=0x71,intB=0xf,intC;intC=intA^intB;printf("intA=%xintB=%xintC=%x\n",intA,intB,intC);}27计算机工程学院该程序利用按位异或运算,将变量intA的低4位取反,高4位保留原值。运行结果如图7-7。图7-7程序EX7_6运行结果

28计算机工程学院【实验7-6】运行下面的程序,分析运行结果:/*EX7_7.CPP*/#include"stdio.h"voidmain(){intintA,intB;scanf("%d,%d",&intA,&intB);printf("intA=%d,intB=%d\n",intA,intB);intA=intA^intB;intB=intB^intA;intA=intA^intB;printf("intA=%d,intB=%d\n",intA,intB);}29计算机工程学院该程序利用按位异或运算,将变量intA与变量intB的值交换,不使用临时变量。假设输入变量intA与变量intB的值分别为:5和6,则运行结果如图7-8。图7-8程序EX7_7运行结果30计算机工程学院

7.1.4拓展与练习

【练习1】试编制编写一个函数getbits,从一个16位的单元中取出某几位(即该几位保留原值,其余为0),函数调用形式为getbits(intvalue,intn1,intn2)。其中value为该16位中的数据值,n1为要取出的起始位,n2为要取出的结束位。31计算机工程学院

任务2文件

学习目标掌握标准设备输入、输出函数的使用;掌握缓冲文件系统的使用。32计算机工程学院

7.2.1案例讲解

案例1

读取指定文件内容1.问题描述:已知一文本文件“c:\text.txt”的内容如下:

#include<stdio.h>voidmain(){printf("helloworld");}编写程序读取指定该文本文件的内容,并在屏幕上输出。33计算机工程学院2.编程分析:程序描述如下:

void

main(){定义文件指针*fileP,定义字符变量charC打开指定的文本文件判断指定的文本文件是否能打开,假如不能打开,显示提示信息,并结束程序使用循环读取该文本文件的每个字符,并依次在屏幕上输出关闭指定的文本文件

}34计算机工程学院3.编写源程序

/*EX7_8.CPP*/#include<stdio.h>#include<conio.h>#include<stdlib.h>voidmain()

{

FILE*fileP;

charcharC;

if((fileP=fopen("c:\\text.txt","r"))==NULL)

{

35计算机工程学院

printf("不能打开文件,按任意键退出!");getchar();exit(1);}while((charC=fgetc(fileP))!=EOF)putchar(charC);fclose(fileP);}4.运行结果36计算机工程学院4.运行结果图7-9案例1运行结果37计算机工程学院5.归纳分析本例程序的功能是从文件中逐个读取字符,在屏幕上显示。程序定义了文件指针fileP,以读文本文件方式打开文件“text.txt”,并使fileP指向该文件。如打开文件出错,给出提示并退出程序。While循环中每次读出一个字符,只要读出的字符不是文件结束标志(每个文件末有一结束标志EOF)就把该字符显示在屏幕上,然后再读入下一字符。每读一次,文件内部的位置指针向后移动一个字符,文件结束时,该指针指向EOF。38计算机工程学院

7.2.2基础理论

1.文件的概念文件是指存储在外部介质上的数据集合体,是操作系统数据管理的单位。使用数据文件的目的:

(1)数据文件的改动不引起程序的改动——程序与数据分离;(2)不同程序可以访问同一数据文件中的数据——数据共享;(3)能长期保存程序运行的中间数据或结果数据。39计算机工程学院2.文件的分类

根据文件存储的内容的不同,文件可以分为程序文件和数据文件两种。程序文件是程序代码的集合体,而数据文件是指专门用来保存数据的文件。根据文件存储介质的不同,文件又可以分为磁盘文件和设备文件两种。磁盘文件是指保存在磁盘或其他外部存储介质上的一个有序数据集,可以是C语言的源文件、目标文件、可执行程序,也可以是一组待输入处理的原始数据,或者是一组输出的结果。对于源文件、目标文件、可执行40计算机工程学院

程序可以称为程序文件,对于输入输出数据可称为数据文件。设备文件是指与主机相联的各种外部设备,如显示器、打印机、磁盘等。C语言把外部设备也看作是一个文件来进行管理,把他们的输入、输出等同于对磁盘文件的读和写。通常把显示器定义为标准输出文件,键盘指定为标准的输入文件。

根据文件的组织形式不同,文件又可以分为ASCII码文件(也称为文本文件)和二进制码文件两种。ASCII码文件,每个字节存放一个字符的ASCII码。二进制码文件,数据按其在内存中的

41计算机工程学院存储形式原样存放。例如:short

int型数10000,在内存中存储占用两个字节,其中1的ASCII为00110001,0的ASCII为00110000,10000的二进制表示为10011100010000。如果分别存储到文本文件和二进制码文件中,其形式如下:图7-10数据存储示意图

42计算机工程学院

从图中可以看出来,ASCII码文件输入与字符一一对应,便于对字符进行逐个处理,也便于字符的输出,但一般占存储空间较多,而且花费二进制代码和ASCII代码之间的转换时间。用二进制文件则可以节省外部存储空间和转换的时间,但处理过程比较复杂。因此,文本文件特点:存储量大、速度慢、便于对字符操作;二进制码文件特点:存储量小、速度快、便于存放中间结果。3.文件的处理在C语言中,对文件的输入输出都是通过文件43计算机工程学院系统完成的,并不区分类型,都看成是字符或者是二进制流,按字节进行处理。输入输出数据流的开始和结束只由程序控制而不受物理符号(如回车换行符)的控制。因此我们也把这种文件称作“流式文件”。文件系统又分为缓冲文件系统和非缓冲文件系统。所谓缓冲文件系统是高级文件系统,系统自动地在内存区为每一个正在使用的文件名开辟一个缓冲区,数据的输入输出都是以这个缓冲区为中介。所谓非缓冲文件系统是低级文件系统,指系统不自动开辟确定大小的缓冲区,而由程序44计算机工程学院为每个文件设定缓冲区。图7-11和图7-12分别是缓冲文件系统和非缓冲文件系统。45计算机工程学院标准C只采用缓冲文件系统,也就是既用缓冲文件系统处理文本文件,也用它来处理二进制文件。在C语言中没有输入输出语句,对文件的读写操作都是用标准的输入输出库函数来实现的。4.缓冲文件系统

(1)FILE类型和文件指针在缓冲文件系统中,使用最多的概念就是“文件指针”。缓冲文件系统为每个使用的文件在内存中开辟一个缓冲区,用来存放文件的相关信息,这些信息被保存在FILE类型的变量中。在stdio.h文件中有FILE类型的定义:46计算机工程学院typedefstruct{shortlevel;/*缓冲区空或满的程度*/unsignedflags;/*文件状态标志*/charfd;/*文件描述符*/unsignedcharhold;/*如无缓冲区则不读取字符*/shortbsize;/*缓冲区的大小*/unsignedchar*buffer;/*数据缓冲区的位置*/unsignedar*curp;/*指针,当前的指向*/unsignedistemp;/*临时文件*/shorttoken;/*用于有效性检查*/}FILE;47计算机工程学院对于普通用户而言,不必了解FILE类型的结构内容,只要知道,每个文件都对应一个唯一的文件型指针变量,通过文件指针我们可以对它所指的文件进行各种操作。定义文件型指针变量的一般形式为:

FILE*指针变量名;例如:FILE*fileP;fileP是指向FILE类型结构体的指针变量,通过fileP即可找存放某个文件信息的结构变量,然后按结构变量提供的信息可以访问该文件,实施对文件的操作。习惯上也48计算机工程学院笼统地把fileP称为指向一个文件的指针。5.文件的操作对文件的基本操作有两种,一种是输入操作,一种是输出操作。在访问文件之前,要先打开文件,然后才能访问该文件,对文件操作结束后,还要关闭该文件。因此对文件的操作,必须遵守“先打开,再读写,后关闭”的规则,也就是说在进行读写操作之前要先打开文件,使用完毕后要关闭。

(1)文件的打开函数fopen

49计算机工程学院

fopen函数用来实现打开一个文件,其调用的一般形式为:

FILE*fileP;

fileP=fopen(文件名,使用文件方式);

其中,“文件名”是被打开文件的文件名,包括文件的存储路径,“使用文件方式”是指文件的类型和操作要求。

例如:fileP=fopen(“file1”,“r”);50计算机工程学院它表示在当前目录下打开文件file1,使用文件方式为“读”操作,并使fileP指向该文件。使用文件的方式共有12种,如表7-1所示.表7-1文件使用方式表51计算机工程学院文件使用方式含义“r”(只读)打开一个文本文件,只允许读数据“w”(只写)

打开或建立一个文本文件,只允许写数据“a”(追加)打开一个文本文件,并在文件末尾增加数据“rb”(只读)打开一个二进制文件,只允许读数据“wb”(只写)打开或建立一个二进制文件,只允许写数据“ab”(追加)打开一个二进制文件,并在文件末尾写数据“r+”(读写)打开一个文本文件,允许读和写“w+”(读写)

建立一个文本文件,允许读写“a+”(读写)打开一个文本文件,允许读,或在文件末追加数据“rb+”(读写)

打开一个二进制文件,允许读和写“wb+”(读写)

建立一个二进制文件,允许读和写“ab+”(读写)打开一个二进制文件,允许读,或在文件末追加数据52计算机工程学院说明:

●用“r”方式打开的文件,该文件必须已经存在,且只能从该文件读出数据。

●用“w”方式打开的文件只能向该文件写入数据。若打开的文件不存在,则以指定的文件名建立该文件,若打开的文件已经存在,则将该文件删去,重建一个新文件。

●如果想向一个已存在的文件末尾添加新的信息(不删除原来的数据),则应该用“a”方式打开。但此时该文件必须是存在的,否则将会出错。

●用“r+”、“w+”、“a+”方式打开的文件既可53计算机工程学院

以用来写入数据,也可以用来读出文件中的数据。如果不能打开一个文件时,fopen将返回一个空指针值NULL。在程序中可以用这一信息来判别是否完成打开文件的工作,并作相应的处理。因此常用以下程序段打开文件:

if((fileP=fopen("file1","r")==NULL){printf("\n不能打开文件file1\n");exit(0);}54计算机工程学院先检查打开的操作是否有错误,既判断返回的指针是否为空,如果有错则给出提示信息“不能打开文件file1”。exit(0)的作用是关闭所有文件,终止程序的执行。文本文件读写操作时要将ASCII码和二进制码之间进行转换,而对二进制文件的读写不存在这种转换。标准输入文件(键盘),标准输出文件(显示器),标准出错输出(出错信息)3个文件是由系统自动打开的,我们可直接使用。55计算机工程学院(2)文件关闭函数fclose文件一旦使用完毕,应该用关闭文件函数把文件关闭,以避免文件的数据丢失等错误。所谓关闭文件就是使文件指针变量不再指向该文件。调用的一般形式是:

fclose(文件指针);例如:fclose(fileP);顺利完成关闭文件操作时,fclose函数返回值为0,否则返回EOF(-1)。56计算机工程学院6.文件的读写和建立文件打开以后,就可以对它进行读写操作了。在C语言中提供了多种文件读写的函数:字符读写函数:fgetc和fputc字符串读写函数:fgets和fputs数据块读写函数:fread和fwrite格式化读写函数:fscanf和fprintf使用以上函数都要求包含头文件stdio.h。57计算机工程学院(1)读字符函数fgetc

fgetc函数的功能是从指定的文件中读一个字符,读取的文件必须是以读或读写方式打开的。调用的形式为:

ch=fgetc(fileP);

fileP为文件型指针变量,ch为字符变量。其意义是从打开的文件fileP中读取一个字符并送入ch中。读字符时遇到文件结束符,函数返回一个文件结束标志EOF(-1)。EOF是在stdio.h文件中定义的符号常量,值为-1。58计算机工程学院(2)写字符函数fputc

fputc函数的功能是把一个字符写入指定的文件中。调用的形式为:

fputc(ch,fileP);

ch是要输出的字符,它可以是字符常量或者是字符变量。fileP为文件型指针变量。其意义是把字符ch写入到fileP所指向的文件中。如果写入成功则返回写入的字符,如果写入失败则返回一个EOF(-1)。(3)读字符串函数fgets

59计算机工程学院fgets函数的功能是从指定的文件中读一个字符串到字符数组中。函数调用的形式为:fgets(str,n,fileP);n是一个正整数,为要求得到的字符数,但从文件中读出的字符串只有n-1个字符,然后在最后一个字符后加上串结束标志'\0',因此得到的字符串共有n个字符。把得到的字符串放在字符数组str里面。fileP为文件型指针变量。如果在读完n-1个字符之前遇到换行符或EOF,读操作即结束。函数返回值为str的首地址。60计算机工程学院(4)写字符串函数fputs

fputs函数的功能是向指定的文件写入一个字符串。函数的调用形式为:

fputs(s,fileP)

s可以是字符串常量,也可以是字符数组名,或字符型指针变量。fileP为文件型指针变量。字符串末尾的’\0’不输出,若输出成功,函数值返回为0,失败则为EOF。7.数据块读写函数fread和fwrite

61计算机工程学院有时候需要读写一组数据,如一个数组的元素,一个结构变量的值等。这时候可以使用读写数据块函数,用来读写一个数据块。函数调用的一般形式为:

fread(buffer,size,count,fileP);fwrite(buffer,size,count,fileP);

其中:buffer是一个指针,在fread函数中,它表示存放输入数据的首地址,在fwrite函数中,它表示存放输出数据的首地址。size

表示要读写的字节数。count

表示要读写的数据块块数(即count个size大的数据块)。fileP表示文件指针。62计算机工程学院8.格式化读写函数fscanf和fprintf

fscanf函数,fprintf函数与前面使用的scanf和printf

函数的功能相似,都是格式化读写函数。不同之处在于fscanf

函数和fprintf函数的读写对象不是键盘和显示器,而是磁盘文件。函数的调用格式为:

fscanf(文件指针,格式字符串,输入表列);

fprintf(文件指针,格式字符串,输出表列);要注意的是,当在内存和磁盘频繁交换数据的情况下,最好不使用这两个函数,而使用fread和fwrite函数。63计算机工程学院9.文件的定位和测试(1)文件的定位上一节介绍的对文件的读写方式都是顺序读写,即读写文件只能从头开始,顺序读写各个数据。但在实际问题中常要求只读写文件中某一指定的部分,也就是移动文件指针到需要读写的位置,再进行读写,这种读写称为随机读写。实现随机读写的关键是按要求移动文件指针,这称为文件的定位。

rewind

函数:调用形式为

rewind(文件指针);64计算机工程学院它的功能是把文件指针重新移到文件的开头。此函数没有返回值。

fseek

函数:fseek函数用来移动文件指针,其调用形式为:

fseek(文件指针,位移量,起始点);其中:“文件指针”指向被移动的文件。“位移量”是指以“起始点”为基点,向前移动的字节数。要求位移量是long型数据,以便在文件的长度大于64K时不会出问题。当用常量表示

65计算机工程学院

位移量时,直接在末尾加后缀“L”。“起始点”表示从文件的什么位置开始计算位移量,规定的起始点有三种:文件首,当前位置和文件尾。其表示方法如表7-2所示。表7-2文件指针三种起始点起始点表示符号数字表示文件首SEEK__SET0当前位置SEEK__CUR1文件末尾SEEK__END266计算机工程学院

fseek函数一般用于二进制文件,这是因为文本文件要进行转换,在计算位置的时候会出现错误。(2)文件检测函数C语言中常用的文件检测函数有以下几个:●文件结束检测函数feof()调用格式:feof(文件指针);功能:判断文件是否处于文件结束位置,如文件结束,则返回值为1,否则为0。●读写文件出错检测函数ferror()调用格式:ferror(文件指针);67计算机工程学院功能:检查文件在用各种输入输出函数进行读写时是否出错。如ferror返回值为0表示未出错,否则表示有错。●文件出错标志和文件结束标志置0函数clearerr()调用格式:clearerr(文件指针);功能:用于清除出错标志和文件结束标志,使它们为0值。68计算机工程学院

7.2.3技能训练

【实验7-7】编写程序,从键盘上输入一系列字符,写到磁盘文件file中,以#作为输入的结束标志,然后把文件中的内容在屏幕上输出。【指导】本实验的功能是执行了两次磁盘文件操作:先用fputc函数把输入的字符放在fileP指向的文件中,然后把文件中的内容用fgetc函数逐个读取,在屏幕上显示。程序定义了文件指针fileP,先以写方式打开文本文件file,并使fileP指向该文件。如打开文件出错,给出提示并退出程序。输入字符到文件中的循环是以输入“#”作为循环结束的标志;69计算机工程学院然后再以读方式打开文本文件file,循环读取文本文件的每一个字符,并显示在屏幕上,并以EOF作为循环的结束标志,也就是判断是否读到文件的结尾。每次文件操作结束后,都要用fclose函数关闭文件。

/*EX7_9.CPP*/#include<stdio.h>#include<conio.h>#include<stdlib.h>voidmain()70计算机工程学院

{ FILE*fileP; charcharC; if((fileP=fopen("file","w"))==NULL) { printf("不能打开文件\n"); exit(0); } printf(“请输入字符:\n”); while((charC=getchar())!=’#’) {71计算机工程学院

fputc(charC,fileP); } fclose(fileP); if((fileP=fopen("file","r"))==NULL) { printf("不能打开文件\n"); exit(0); } printf("文件内容为:\n"); charC=fgetc(fileP);72计算机工程学院

while(charC!=EOF) { putchar(charC); charC=fgetc(fileP); } fclose(fileP); }该程序首先打开当前目录中文件名为file的文件,然后从键盘上输入字符并存储到文件file

73计算机工程学院中,输入完成后关闭文件file,最后再次打开文件file,并输出文件file中的字符。图7-13为该程序的一次运行实例.图7-13程序EX7_9运行结果74计算机工程学院【实验7-8】有两个磁盘文件a1.txt和a2.txt,各存放若干行字母,今要求把这两个文件中的信息按行交叉合并(即先是a1.txt的的第一行,接着是a2.txt中的第一行,然后是a1.txt的第二行,跟着是a2.txt的第二行,…),输出到一个新文件a3.txt中去。【指导】以读方式打开磁盘文件a1.txt和a2.txt,然后依次读取a1.txt和a2.txt的一行,交叉存入新文件a3.txt,因此可以通过3个循环语句实现。具体做法为:通过fgets函数分别获得文件a1.txt和a2.txt中的每一行字符,分别赋值给字符数组str1和str2,然后将字符数组str1和75计算机工程学院

str2中的内容依次写入文件a3.txt。假如其中某个文件读取完成,则将另一文件剩余行写人文件a3.txt后部。

/*EX7_10.CPP*/#include<stdio.h>#include<conio.h>#include<stdlib.h>voidmain(){FILE*fp1,*fp2,*fp3;charstr1[255],str2[255];if((fp1=fopen("a1.txt","r"))==NULL)76计算机工程学院

{printf("filea1cannotbeopened\n");exit(0);}if((fp2=fopen("a2.txt","r"))==NULL){printf("filea2cannotbeopened\n");exit(0);}if((fp3=fopen("a3.txt","w+"))==NULL){printf("filea3cannotbeopened\n");exit(0);}while(fgets(str1,255,fp1)!=NULL&&fgets(str2,255,fp2)!=NULL){fputs(str1,fp3);fputs(str2,fp3);}while(fgets(str1,255,fp1)!=NULL)

77计算机工程学院

{fputs(str1,fp3);}while(fgets(str2,255,fp2)!=NULL){fputs(str2,fp3);}/*charcharC;//以下注释掉的代码,为查看文件a1、a2、a3的内容,以检查运行效果rewind(fp1);rewind(fp2);rewind(fp3);printf("a1文件内容为:\n");78计算机工程学院charC=fgetc(fp1);while(charC!=EOF){putchar(charC);charC=fgetc(fp1);}printf("a2文件内容为:\n");charC=fgetc(fp2);while(charC!=EOF){putchar(charC);charC=fgetc(fp2);}79计算机工程学院printf("a3文件内容为:\n");charC=fgetc(fp3);while(charC!=EOF){putchar(charC);charC=fgetc(fp3);}*/fclose(fp1);fclose(fp2);fclose(fp3);}去掉上述代码中的注释符号,该程序的一次运行实例如下图7-14。80计算机工程学院图7-14程序EX7_10运行结果81计算机工程学院【实验7-9】从键盘输入两个学生数据,写入一个文件中,再读出这两个学生的数据显示在屏幕上。【指导】该实验需要一个数据结构来存储学生信息,因此需要定义一个学生结构体。并将输入后的学生信息写入文件,再读出该文件的内容,显示在屏幕上。每个学生的信息包含一组数据,因此使用数据块读写函数fread和fwrite来完成对文件的读写,程序如下。

/*EX7_11.CPP*/#include<stdio.h>82计算机工程学院#include<conio.h>#include<stdlib.h>structstu{ charname[10]; intnum; intage; charaddr[20];}stu_1[2],stu_2[2],*p,*q;voidmain(){83计算机工程学院 FILE*fp; p=stu_1; q=stu_2; inti; if((fp=fopen("stu_list","wb+"))==NULL) { printf("Cannotopenfilestrikeanykeyexit!"); exit(0); } printf("inputdata\n"); for(i=0;i<2;i++,p++)84计算机工程学院 scanf("%s%d%d%s",p->name,&p->num,&p->age,p->addr); p=stu_1; fwrite(p,sizeof(structstu),2,fp); rewind(fp); fread(q,sizeof(structstu),2,fp); printf("NAME\tNUMBER\tAGE\tADDR\n"); for(i=0;i<2;i++,q++) printf("%s\t%5d%7d\t%s\n",q->name,q->num,q->age,q->addr); fclose(fp);}85计算机工程学院本例程序定义了一个结构stu,说明了两个结构数组stu_1和stu_2以及两个结构指针变量p和q。p指向stu_1,q指向stu_2。程序以读写方式打开二进制文件“stu_list”,输入二个学生数据之后,写入该文件中,然后用rewind函数把文件内部位置指针重新移到文件首,读出两个学生数据后,在屏幕上显示。86计算机工程学院图7-15程序EX7_11运行结果【实验7-10】用fscanf和fprintf函数完成实验7-9的问题。【指导】与函数fread和fwrite相比,fscanf和fprintf函数每次只能读写一个结构数组元素,因此采用了循环语句来读写全部数组元素,程序87计算机工程学院如下。

/*EX7_12.CPP*/#include<stdio.h>#include<conio.h>#include<stdlib.h>structstu{charname[10];intnum;intage;charaddr[20];}stu_1[2],stu_2[2],*p,*q;88计算机工程学院main(){ FILE*fp; p=stu_1; q=stu_2; inti; if((fp=fopen("stu_list","wb+"))==NULL) { printf("Cannotopenfilestrikeanykeyexit!"); exit(0); } printf("inputdata\n");89计算机工程学院 for(i=0;i<2;i++,p++) scanf("%s%d%d%s",p->name,&p->num,&p->age,p->addr); p=stu_1; for(i=0;i<2;i++,p++) fprintf(fp,"%s%d%d%s\n",p->name,p->num,p->age,p->addr); rewind(fp); for(i=0;i<2;i++,q++) fscanf(fp,"%s%d%d%s\n",q->name,&q->num,&q->age,q->addr); printf("NAME\tNUMBER\tAGE\tADDR\n");90计算机工程学院 q=stu_2; for(i=0;i<2;i++,q++) printf("%s\t%5d%7d\t%s\n",q->name,q->num,q->age,q->addr); fclose(fp);}本程序中fscanf和fprintf函数每次只能读写一个结构数组元素,因此采用了循环语句来读写全部数组元素。还要注意指针变量p,q由于循环改变了它们的值,因此在程序中分别对它们重新赋予了数组的首地址。91计算机工程学院图7-16程序EX7_12运行结果【实验7-11】在学生文件stu_list中读出第二个学生的数据。【指导】前两个实验对文件的读取都是顺序读出,而该实验只读写文件stu_list中某一指定部分的内容。因此用函数fseek先将文件内部的位置92计算机工程学院指针移动到需要读写的位置,然后再使用函数fread读取指定数据。/*EX7_13.CPP*/#include<stdio.h>#include<conio.h>#include<stdlib.h>structstu{charname[10];intnum;93计算机工程学院intage;charaddr[20];}student,*p;main(){ FILE*fp;inti=1;p=&student;if((fp=fopen("stu_list","rb"))==NULL){printf("Cannotopenfilestrikeanykeyexit!");getch()();94计算机工程学院exit(1);}rewind(fp);fseek(fp,i*sizeof(structstu),0);fread(p,sizeof(structstu),1,fp);printf("name\tnumber\tageaddr\n");printf("%s\t%5d%7d%s\n",p->name,p->num,p->age,p->addr);}该程序的一次运行实例如下图7-17。95计算机工程学院图7-17程序EX7_13运行结果96计算机工程学院

7.2.4拓展与练习

【练习1】利用本章的学习内容实现简单的文件加密。【指导】每次对原文中的一个字符进行加密,再将加密后的这个字符存储到密文,直到将原文中的每个字符做如上处理后,才结束该加密程序。具体做法为:首先通过键盘输入加密密钥,然后读取原文中的每一个字符,与加密密钥进行异或操作,得到该字符的加密密文,然后将该加密密文存入密文中,直到处理完原文中的每个字符,程序如下。97计算机工程学院/*EX7_14.CPP*/#include<stdio.h>#include<conio.h>#include<stdlib.h>voidmain(){ FILE*originalfile,*Cipherfile; charcharC; intintCipher; intintN; printf("请输入密钥intN的值:");98计算机工程学院 scanf("%d",&intN); if((originalfile=fopen("test","rb"))==NULL) { printf("不能打开文件\n"); exit(0); } if((Cipherfile=fopen("Ciphertext","wb"))==NULL) { printf("不能打开文件\n"); exit(0); } charC=fgetc(originalfile); while(charC!=EOF) {99计算机工程学院 intCipher=(int)(charC)^intN; fputc((char)(intCipher),Cipherfile); charC=fgetc(originalfile); }fclose(Cipherfile);fclose(originalfile);}该程序实现了较简单对称加密的一种算法。在C语言中,一个int型数据占2个字节,因此该程序可以有65536个加密密钥。现假设输入加密密钥1234,其执行效果如图7-18至图7-20。100计算机工程学院图7-18程序EX7_14运行结果图7-19程序EX7_14加密前原文内容101计算机工程学院图7-20程序EX7_14加密后密文内容102计算机工程学院此外,该实例只是为了说明通过C语言中的位运算与文件处理解决问题的方法。在实际中,加密算法要复杂得多,对它的处理相对也比较复杂。例如该程序可以使用不同的加密密钥进行多次加密,或者配合使用其他位运算,对原文实现非对称加密等方法,都可以增加密文的破解难度,以达到文件传输过程中的安全性。解密为加密的逆过程,因此解密程序可以作为课后练习,由自己编程运行。103计算机工程学院

7.2.5编程规范与常见错误

1.使用文件时忘记打开文件;2.用只读方式打开,却企图向该文件输出数据;3.文件使用完,忘记关闭文件等错误。因此文件打开前,应做到对文件的状态进行检查。104计算机工程学院

7.2.6贯通案例之八

1.问题描述:在贯通案例七的基础上实现学生成绩管理系统的加载文件,保存文件两个功能。2.编写程序/*函数功能:保存学生记录文件 函数参数:结构体指针head,指向存储学生信息的结构体数组的首地址 整型变量n,表示学生人数 整型变量m,表示考试科目函数返回值:无*/105计算机工程学院/*EX7_15.CPP*/voidSaveScoreFile(STU*head,constintn,constintm){ FILE*fp; inti; STU*p=head; if((fp=fopen("record","wb"))==NULL) { printf("cannotopenfile\n"); exit(1); }106计算机工程学院 printf("\nSavingfile\n"); fwrite(&n,sizeof(int),1,fp); fwrite(&m,sizeof(int),1,fp); for(i=0;i<n;i++) { fwrite(head+i,sizeof

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论