模塊7-位運(yùn)算與文件_第1頁
模塊7-位運(yùn)算與文件_第2頁
模塊7-位運(yùn)算與文件_第3頁
模塊7-位運(yùn)算與文件_第4頁
模塊7-位運(yùn)算與文件_第5頁
已閱讀5頁,還剩115頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1

C語言程序設(shè)計任務(wù)式教程(微課版)

VisualC++2計算機(jī)工程學(xué)院模塊7位運(yùn)算與文件

任務(wù)1位運(yùn)算任務(wù)2文件

3計算機(jī)工程學(xué)院任務(wù)1位運(yùn)算學(xué)習(xí)目標(biāo)掌握六種位運(yùn)算的運(yùn)算符與格式、運(yùn)算規(guī)則。n位n位圖7-1二進(jìn)制的循環(huán)移位圖解4計算機(jī)工程學(xué)院案例1二進(jìn)制的循環(huán)移位1.問題描述

實現(xiàn)二進(jìn)制的循環(huán)移位。設(shè)待移位的數(shù)為a,移位情況如圖示,假設(shè)系統(tǒng)中2個字節(jié)存放一個整數(shù)。

7.1.1案例講解

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

該問題的要求,在于將待移位數(shù)a分成兩部分,然后交換這兩部分的位置。從而可知,需要增加兩個變量來存儲變量a的兩部分的值,而這些操作都需要求助于位運(yùn)算。程序描述如下:5計算機(jī)工程學(xué)院voidmain(){定義無符號整型變量a,b,c定義整型變量n輸入待移動數(shù)a和所移動位數(shù)n對數(shù)a左移16-n位后的結(jié)果給變量b對數(shù)a右移n位后的結(jié)果給變量c對變量b,c做按位或運(yùn)算,計算結(jié)果給變量c輸出變量a和c}n位n位圖7-1二進(jìn)制的循環(huán)移位圖解6計算機(jī)工程學(xué)院3.編寫源程序/*EX7_1.CPP*/#include<stdio.h>voidmain(){unsignedshortunsignedA,unsignedB,unsignedC;intintN;printf("請輸入一個無符號整型變量unsignedA的值:");scanf("%u",&unsignedA);printf("請輸入移位位數(shù)intN的值:");7計算機(jī)工程學(xué)院

scanf("%d",&intN);unsignedB=unsignedA<<(16–intN);unsignedC=unsignedA>>intN;unsignedC=unsignedC|unsignedB;printf("unsignedA的值:%o\n",unsignedA);printf("unsignedC的值:%o\n",unsignedC);}4.運(yùn)行結(jié)果8計算機(jī)工程學(xué)院圖7-2案例1運(yùn)行結(jié)果5.歸納分析在本案例中,使用了左移位運(yùn)算、右移位運(yùn)算和按位或運(yùn)算相配合,實現(xiàn)二進(jìn)制的循環(huán)移位。9計算機(jī)工程學(xué)院該程序運(yùn)行的一個實例,輸入unsignedA的值為174,移動位數(shù)intN的值為2,則運(yùn)行結(jié)果如圖。其中:十進(jìn)制數(shù)174(即為八進(jìn)制數(shù)256)的二進(jìn)制數(shù)為0000000010101110(按題設(shè)要求為2個字節(jié)),循環(huán)移動2位,則循環(huán)移位后的二進(jìn)制結(jié)果為1000000000101011(即為八進(jìn)制數(shù)100053)。A:0000000010101110(AE174)循環(huán)移動2位:1000000000101011(802B)10計算機(jī)工程學(xué)院

7.1.2基礎(chǔ)理論

C語言中提供給開發(fā)人員一種位的運(yùn)算,這種位的運(yùn)算常用在檢測和控制領(lǐng)域中,這和C語言的特性關(guān)系非常大,因為C語言是具有高級語言的特點和低級語言的功能,能完成一些匯編語言所能完成的功能。給開發(fā)人員提供了一定的簡便。C語言提供了六種位運(yùn)算,下面分別介紹。1.按位與運(yùn)算(&)

(1)格式:x&y(2)規(guī)則:按位與運(yùn)算符“&”是雙目運(yùn)算符。其功能是參加運(yùn)算的兩數(shù)各對應(yīng)的二進(jìn)位相與。只有對應(yīng)的兩個二進(jìn)位均為1時,結(jié)果位才為1,11計算機(jī)工程學(xué)院否則為0。參加運(yùn)算的數(shù)以補(bǔ)碼方式出現(xiàn)。例如:9&5可寫算式如下

00001001

&0000010100000001結(jié)果為:9&5=1。(3)主要用途:用來對某些位清0或保留某些位。例如:把a(bǔ)的高八位清0,保留低八位,可作a&255運(yùn)算(255的二進(jìn)制數(shù)為0000000011111111)。12計算機(jī)工程學(xué)院2.按位或運(yùn)算符(|)(1)格式:x|y(2)規(guī)則:按位或運(yùn)算符“|”是雙目運(yùn)算符。其功能是參加運(yùn)算的兩數(shù)各對應(yīng)的二進(jìn)位相或。只要對應(yīng)的二個二進(jìn)位有一個為1時,結(jié)果位就為1。參加運(yùn)算的兩個數(shù)均以補(bǔ)碼出現(xiàn)。例如:9|5可寫算式如下

00001001

|0000010100001101結(jié)果為:9|5=1313計算機(jī)工程學(xué)院

(3)主要用途:常用來將源操作數(shù)某些位置1,其他位不變。例如:把a(bǔ)的低八位置1,保留高八位,可作a|255運(yùn)算(255的二進(jìn)制數(shù)為0000000011111111)。3.按位異或運(yùn)算(^)

(1)格式:x^y(2)規(guī)則:按位異或運(yùn)算符“^”是雙目運(yùn)算符。其功能是參加運(yùn)算的兩數(shù)各對應(yīng)的二進(jìn)位相異或,當(dāng)兩對應(yīng)的二進(jìn)位相異時,結(jié)果為1。參加運(yùn)算數(shù)仍以補(bǔ)碼出現(xiàn)。例如:9^5可寫成算式如下14計算機(jī)工程學(xué)院

00001001

^0000010100001100

結(jié)果為:9^5=12

(3)主要用途:常用來將源操作數(shù)某些特定位的值取反,其他位不變。

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

運(yùn)算(255

的二進(jìn)制數(shù)為0000000011111111)。15計算機(jī)工程學(xué)院4.求反運(yùn)算(~)

(1)格式:~x(2)規(guī)則:求反運(yùn)算符~為單目運(yùn)算符,具備右結(jié)合性。其功能是對參加運(yùn)算的數(shù)的各二進(jìn)位按位求反。例如:~9可寫成算式如下

~00000000000010011111111111110110結(jié)果為:~9=-1016計算機(jī)工程學(xué)院5.左移運(yùn)算(<<)(1)格式:x<<位數(shù)(2)規(guī)則:左移運(yùn)算符“<<”是雙目運(yùn)算符。其功能是把“<<”左邊的運(yùn)算數(shù)的各二進(jìn)位全部左移若干位,“<<”右邊的數(shù)指定移動的位數(shù)。低位補(bǔ)0,高位溢出。例如:設(shè)a=15,a<<2表示把000001111左移為00111100(十進(jìn)制60)。17計算機(jī)工程學(xué)院6.位右移(>>)(1)格式:x>>位數(shù)(2)規(guī)則:使操作數(shù)的各位右移,高位補(bǔ)0,低位溢出。例如:5>>2=100000101右移兩位

0000000118計算機(jī)工程學(xué)院

7.1.3技能訓(xùn)練

【實驗7-1】運(yùn)行下面的程序,分析運(yùn)行結(jié)果。

/*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計算機(jī)工程學(xué)院該程序利用按位與運(yùn)算,把變量a的所有位清0。運(yùn)行結(jié)果如圖7-3所示。圖7-3程序EX7_2運(yùn)行結(jié)果20計算機(jī)工程學(xué)院【實驗7-2】運(yùn)行下面的程序,分析運(yùn)行結(jié)果。

/*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計算機(jī)工程學(xué)院該程序利用按位與運(yùn)算,把變量a的高八位清0,保留低八位。假設(shè)輸入變量intA的值為:12345,則運(yùn)行結(jié)果如圖7-4。圖7-4程序EX7_3運(yùn)行結(jié)果22計算機(jī)工程學(xué)院【實驗7-3】運(yùn)行下面的程序,分析運(yùn)行結(jié)果:

/*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計算機(jī)工程學(xué)院該程序利用按位與運(yùn)算,把變量intA的最低位取出。運(yùn)行結(jié)果如圖7-5。圖7-5程序EX7_4運(yùn)行結(jié)果24計算機(jī)工程學(xué)院【實驗7-4】運(yùn)行下面的程序,分析運(yùn)行結(jié)果:

/*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計算機(jī)工程學(xué)院該程序利用按位或運(yùn)算,將變量intA的低5位置為1。假設(shè)輸入變量intA的值為:6,則運(yùn)行結(jié)果如圖7-6。圖7-6程序EX7_5運(yùn)行結(jié)果26計算機(jī)工程學(xué)院【實驗7-5】運(yùn)行下面的程序,分析運(yùn)行結(jié)果:

/*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計算機(jī)工程學(xué)院該程序利用按位異或運(yùn)算,將變量intA的低4位取反,高4位保留原值。運(yùn)行結(jié)果如圖7-7。圖7-7程序EX7_6運(yùn)行結(jié)果

28計算機(jī)工程學(xué)院【實驗7-6】運(yùn)行下面的程序,分析運(yùn)行結(jié)果:/*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計算機(jī)工程學(xué)院該程序利用按位異或運(yùn)算,將變量intA與變量intB的值交換,不使用臨時變量。假設(shè)輸入變量intA與變量intB的值分別為:5和6,則運(yùn)行結(jié)果如圖7-8。圖7-8程序EX7_7運(yùn)行結(jié)果30計算機(jī)工程學(xué)院

7.1.4拓展與練習(xí)

【練習(xí)1】試編制編寫一個函數(shù)getbits,從一個16位的單元中取出某幾位(即該幾位保留原值,其余為0),函數(shù)調(diào)用形式為getbits(intvalue,intn1,intn2)。其中value為該16位中的數(shù)據(jù)值,n1為要取出的起始位,n2為要取出的結(jié)束位。31計算機(jī)工程學(xué)院

任務(wù)2文件

學(xué)習(xí)目標(biāo)掌握標(biāo)準(zhǔn)設(shè)備輸入、輸出函數(shù)的使用;掌握緩沖文件系統(tǒng)的使用。32計算機(jī)工程學(xué)院

7.2.1案例講解

案例1

讀取指定文件內(nèi)容1.問題描述:已知一文本文件“c:\text.txt”的內(nèi)容如下:

#include<stdio.h>voidmain(){printf("helloworld");}編寫程序讀取指定該文本文件的內(nèi)容,并在屏幕上輸出。33計算機(jī)工程學(xué)院2.編程分析:程序描述如下:

void

main(){定義文件指針*fileP,定義字符變量charC打開指定的文本文件判斷指定的文本文件是否能打開,假如不能打開,顯示提示信息,并結(jié)束程序使用循環(huán)讀取該文本文件的每個字符,并依次在屏幕上輸出關(guān)閉指定的文本文件

}34計算機(jī)工程學(xué)院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計算機(jī)工程學(xué)院

printf("不能打開文件,按任意鍵退出!");getchar();exit(1);}while((charC=fgetc(fileP))!=EOF)putchar(charC);fclose(fileP);}4.運(yùn)行結(jié)果36計算機(jī)工程學(xué)院4.運(yùn)行結(jié)果圖7-9案例1運(yùn)行結(jié)果37計算機(jī)工程學(xué)院5.歸納分析本例程序的功能是從文件中逐個讀取字符,在屏幕上顯示。程序定義了文件指針fileP,以讀文本文件方式打開文件“text.txt”,并使fileP指向該文件。如打開文件出錯,給出提示并退出程序。While循環(huán)中每次讀出一個字符,只要讀出的字符不是文件結(jié)束標(biāo)志(每個文件末有一結(jié)束標(biāo)志EOF)就把該字符顯示在屏幕上,然后再讀入下一字符。每讀一次,文件內(nèi)部的位置指針向后移動一個字符,文件結(jié)束時,該指針指向EOF。38計算機(jī)工程學(xué)院

7.2.2基礎(chǔ)理論

1.文件的概念文件是指存儲在外部介質(zhì)上的數(shù)據(jù)集合體,是操作系統(tǒng)數(shù)據(jù)管理的單位。使用數(shù)據(jù)文件的目的:

(1)數(shù)據(jù)文件的改動不引起程序的改動——程序與數(shù)據(jù)分離;(2)不同程序可以訪問同一數(shù)據(jù)文件中的數(shù)據(jù)——數(shù)據(jù)共享;(3)能長期保存程序運(yùn)行的中間數(shù)據(jù)或結(jié)果數(shù)據(jù)。39計算機(jī)工程學(xué)院2.文件的分類

根據(jù)文件存儲的內(nèi)容的不同,文件可以分為程序文件和數(shù)據(jù)文件兩種。程序文件是程序代碼的集合體,而數(shù)據(jù)文件是指專門用來保存數(shù)據(jù)的文件。根據(jù)文件存儲介質(zhì)的不同,文件又可以分為磁盤文件和設(shè)備文件兩種。磁盤文件是指保存在磁盤或其他外部存儲介質(zhì)上的一個有序數(shù)據(jù)集,可以是C語言的源文件、目標(biāo)文件、可執(zhí)行程序,也可以是一組待輸入處理的原始數(shù)據(jù),或者是一組輸出的結(jié)果。對于源文件、目標(biāo)文件、可執(zhí)行40計算機(jī)工程學(xué)院

程序可以稱為程序文件,對于輸入輸出數(shù)據(jù)可稱為數(shù)據(jù)文件。設(shè)備文件是指與主機(jī)相聯(lián)的各種外部設(shè)備,如顯示器、打印機(jī)、磁盤等。C語言把外部設(shè)備也看作是一個文件來進(jìn)行管理,把他們的輸入、輸出等同于對磁盤文件的讀和寫。通常把顯示器定義為標(biāo)準(zhǔn)輸出文件,鍵盤指定為標(biāo)準(zhǔn)的輸入文件。

根據(jù)文件的組織形式不同,文件又可以分為ASCII碼文件(也稱為文本文件)和二進(jìn)制碼文件兩種。ASCII碼文件,每個字節(jié)存放一個字符的ASCII碼。二進(jìn)制碼文件,數(shù)據(jù)按其在內(nèi)存中的

41計算機(jī)工程學(xué)院存儲形式原樣存放。例如:short

int型數(shù)10000,在內(nèi)存中存儲占用兩個字節(jié),其中1的ASCII為00110001,0的ASCII為00110000,10000的二進(jìn)制表示為10011100010000。如果分別存儲到文本文件和二進(jìn)制碼文件中,其形式如下:圖7-10數(shù)據(jù)存儲示意圖

42計算機(jī)工程學(xué)院

從圖中可以看出來,ASCII碼文件輸入與字符一一對應(yīng),便于對字符進(jìn)行逐個處理,也便于字符的輸出,但一般占存儲空間較多,而且花費(fèi)二進(jìn)制代碼和ASCII代碼之間的轉(zhuǎn)換時間。用二進(jìn)制文件則可以節(jié)省外部存儲空間和轉(zhuǎn)換的時間,但處理過程比較復(fù)雜。因此,文本文件特點:存儲量大、速度慢、便于對字符操作;二進(jìn)制碼文件特點:存儲量小、速度快、便于存放中間結(jié)果。3.文件的處理在C語言中,對文件的輸入輸出都是通過文件43計算機(jī)工程學(xué)院系統(tǒng)完成的,并不區(qū)分類型,都看成是字符或者是二進(jìn)制流,按字節(jié)進(jìn)行處理。輸入輸出數(shù)據(jù)流的開始和結(jié)束只由程序控制而不受物理符號(如回車換行符)的控制。因此我們也把這種文件稱作“流式文件”。文件系統(tǒng)又分為緩沖文件系統(tǒng)和非緩沖文件系統(tǒng)。所謂緩沖文件系統(tǒng)是高級文件系統(tǒng),系統(tǒng)自動地在內(nèi)存區(qū)為每一個正在使用的文件名開辟一個緩沖區(qū),數(shù)據(jù)的輸入輸出都是以這個緩沖區(qū)為中介。所謂非緩沖文件系統(tǒng)是低級文件系統(tǒng),指系統(tǒng)不自動開辟確定大小的緩沖區(qū),而由程序44計算機(jī)工程學(xué)院為每個文件設(shè)定緩沖區(qū)。圖7-11和圖7-12分別是緩沖文件系統(tǒng)和非緩沖文件系統(tǒng)。45計算機(jī)工程學(xué)院標(biāo)準(zhǔn)C只采用緩沖文件系統(tǒng),也就是既用緩沖文件系統(tǒng)處理文本文件,也用它來處理二進(jìn)制文件。在C語言中沒有輸入輸出語句,對文件的讀寫操作都是用標(biāo)準(zhǔn)的輸入輸出庫函數(shù)來實現(xiàn)的。4.緩沖文件系統(tǒng)

(1)FILE類型和文件指針在緩沖文件系統(tǒng)中,使用最多的概念就是“文件指針”。緩沖文件系統(tǒng)為每個使用的文件在內(nèi)存中開辟一個緩沖區(qū),用來存放文件的相關(guān)信息,這些信息被保存在FILE類型的變量中。在stdio.h文件中有FILE類型的定義:46計算機(jī)工程學(xué)院typedefstruct{shortlevel;/*緩沖區(qū)空或滿的程度*/unsignedflags;/*文件狀態(tài)標(biāo)志*/charfd;/*文件描述符*/unsignedcharhold;/*如無緩沖區(qū)則不讀取字符*/shortbsize;/*緩沖區(qū)的大小*/unsignedchar*buffer;/*數(shù)據(jù)緩沖區(qū)的位置*/unsignedar*curp;/*指針,當(dāng)前的指向*/unsignedistemp;/*臨時文件*/shorttoken;/*用于有效性檢查*/}FILE;47計算機(jī)工程學(xué)院對于普通用戶而言,不必了解FILE類型的結(jié)構(gòu)內(nèi)容,只要知道,每個文件都對應(yīng)一個唯一的文件型指針變量,通過文件指針我們可以對它所指的文件進(jìn)行各種操作。定義文件型指針變量的一般形式為:

FILE*指針變量名;例如:FILE*fileP;fileP是指向FILE類型結(jié)構(gòu)體的指針變量,通過fileP即可找存放某個文件信息的結(jié)構(gòu)變量,然后按結(jié)構(gòu)變量提供的信息可以訪問該文件,實施對文件的操作。習(xí)慣上也48計算機(jī)工程學(xué)院籠統(tǒng)地把fileP稱為指向一個文件的指針。5.文件的操作對文件的基本操作有兩種,一種是輸入操作,一種是輸出操作。在訪問文件之前,要先打開文件,然后才能訪問該文件,對文件操作結(jié)束后,還要關(guān)閉該文件。因此對文件的操作,必須遵守“先打開,再讀寫,后關(guān)閉”的規(guī)則,也就是說在進(jìn)行讀寫操作之前要先打開文件,使用完畢后要關(guān)閉。

(1)文件的打開函數(shù)fopen

49計算機(jī)工程學(xué)院

fopen函數(shù)用來實現(xiàn)打開一個文件,其調(diào)用的一般形式為:

FILE*fileP;

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

其中,“文件名”是被打開文件的文件名,包括文件的存儲路徑,“使用文件方式”是指文件的類型和操作要求。

例如:fileP=fopen(“file1”,“r”);50計算機(jī)工程學(xué)院它表示在當(dāng)前目錄下打開文件file1,使用文件方式為“讀”操作,并使fileP指向該文件。使用文件的方式共有12種,如表7-1所示.表7-1文件使用方式表51計算機(jī)工程學(xué)院文件使用方式含義“r”(只讀)打開一個文本文件,只允許讀數(shù)據(jù)“w”(只寫)

打開或建立一個文本文件,只允許寫數(shù)據(jù)“a”(追加)打開一個文本文件,并在文件末尾增加數(shù)據(jù)“rb”(只讀)打開一個二進(jìn)制文件,只允許讀數(shù)據(jù)“wb”(只寫)打開或建立一個二進(jìn)制文件,只允許寫數(shù)據(jù)“ab”(追加)打開一個二進(jìn)制文件,并在文件末尾寫數(shù)據(jù)“r+”(讀寫)打開一個文本文件,允許讀和寫“w+”(讀寫)

建立一個文本文件,允許讀寫“a+”(讀寫)打開一個文本文件,允許讀,或在文件末追加數(shù)據(jù)“rb+”(讀寫)

打開一個二進(jìn)制文件,允許讀和寫“wb+”(讀寫)

建立一個二進(jìn)制文件,允許讀和寫“ab+”(讀寫)打開一個二進(jìn)制文件,允許讀,或在文件末追加數(shù)據(jù)52計算機(jī)工程學(xué)院說明:

●用“r”方式打開的文件,該文件必須已經(jīng)存在,且只能從該文件讀出數(shù)據(jù)。

●用“w”方式打開的文件只能向該文件寫入數(shù)據(jù)。若打開的文件不存在,則以指定的文件名建立該文件,若打開的文件已經(jīng)存在,則將該文件刪去,重建一個新文件。

●如果想向一個已存在的文件末尾添加新的信息(不刪除原來的數(shù)據(jù)),則應(yīng)該用“a”方式打開。但此時該文件必須是存在的,否則將會出錯。

●用“r+”、“w+”、“a+”方式打開的文件既可53計算機(jī)工程學(xué)院

以用來寫入數(shù)據(jù),也可以用來讀出文件中的數(shù)據(jù)。如果不能打開一個文件時,fopen將返回一個空指針值NULL。在程序中可以用這一信息來判別是否完成打開文件的工作,并作相應(yīng)的處理。因此常用以下程序段打開文件:

if((fileP=fopen("file1","r")==NULL){printf("\n不能打開文件file1\n");exit(0);}54計算機(jī)工程學(xué)院先檢查打開的操作是否有錯誤,既判斷返回的指針是否為空,如果有錯則給出提示信息“不能打開文件file1”。exit(0)的作用是關(guān)閉所有文件,終止程序的執(zhí)行。文本文件讀寫操作時要將ASCII碼和二進(jìn)制碼之間進(jìn)行轉(zhuǎn)換,而對二進(jìn)制文件的讀寫不存在這種轉(zhuǎn)換。標(biāo)準(zhǔn)輸入文件(鍵盤),標(biāo)準(zhǔn)輸出文件(顯示器),標(biāo)準(zhǔn)出錯輸出(出錯信息)3個文件是由系統(tǒng)自動打開的,我們可直接使用。55計算機(jī)工程學(xué)院(2)文件關(guān)閉函數(shù)fclose文件一旦使用完畢,應(yīng)該用關(guān)閉文件函數(shù)把文件關(guān)閉,以避免文件的數(shù)據(jù)丟失等錯誤。所謂關(guān)閉文件就是使文件指針變量不再指向該文件。調(diào)用的一般形式是:

fclose(文件指針);例如:fclose(fileP);順利完成關(guān)閉文件操作時,fclose函數(shù)返回值為0,否則返回EOF(-1)。56計算機(jī)工程學(xué)院6.文件的讀寫和建立文件打開以后,就可以對它進(jìn)行讀寫操作了。在C語言中提供了多種文件讀寫的函數(shù):字符讀寫函數(shù):fgetc和fputc字符串讀寫函數(shù):fgets和fputs數(shù)據(jù)塊讀寫函數(shù):fread和fwrite格式化讀寫函數(shù):fscanf和fprintf使用以上函數(shù)都要求包含頭文件stdio.h。57計算機(jī)工程學(xué)院(1)讀字符函數(shù)fgetc

fgetc函數(shù)的功能是從指定的文件中讀一個字符,讀取的文件必須是以讀或讀寫方式打開的。調(diào)用的形式為:

ch=fgetc(fileP);

fileP為文件型指針變量,ch為字符變量。其意義是從打開的文件fileP中讀取一個字符并送入ch中。讀字符時遇到文件結(jié)束符,函數(shù)返回一個文件結(jié)束標(biāo)志EOF(-1)。EOF是在stdio.h文件中定義的符號常量,值為-1。58計算機(jī)工程學(xué)院(2)寫字符函數(shù)fputc

fputc函數(shù)的功能是把一個字符寫入指定的文件中。調(diào)用的形式為:

fputc(ch,fileP);

ch是要輸出的字符,它可以是字符常量或者是字符變量。fileP為文件型指針變量。其意義是把字符ch寫入到fileP所指向的文件中。如果寫入成功則返回寫入的字符,如果寫入失敗則返回一個EOF(-1)。(3)讀字符串函數(shù)fgets

59計算機(jī)工程學(xué)院fgets函數(shù)的功能是從指定的文件中讀一個字符串到字符數(shù)組中。函數(shù)調(diào)用的形式為:fgets(str,n,fileP);n是一個正整數(shù),為要求得到的字符數(shù),但從文件中讀出的字符串只有n-1個字符,然后在最后一個字符后加上串結(jié)束標(biāo)志'\0',因此得到的字符串共有n個字符。把得到的字符串放在字符數(shù)組str里面。fileP為文件型指針變量。如果在讀完n-1個字符之前遇到換行符或EOF,讀操作即結(jié)束。函數(shù)返回值為str的首地址。60計算機(jī)工程學(xué)院(4)寫字符串函數(shù)fputs

fputs函數(shù)的功能是向指定的文件寫入一個字符串。函數(shù)的調(diào)用形式為:

fputs(s,fileP)

s可以是字符串常量,也可以是字符數(shù)組名,或字符型指針變量。fileP為文件型指針變量。字符串末尾的’\0’不輸出,若輸出成功,函數(shù)值返回為0,失敗則為EOF。7.?dāng)?shù)據(jù)塊讀寫函數(shù)fread和fwrite

61計算機(jī)工程學(xué)院有時候需要讀寫一組數(shù)據(jù),如一個數(shù)組的元素,一個結(jié)構(gòu)變量的值等。這時候可以使用讀寫數(shù)據(jù)塊函數(shù),用來讀寫一個數(shù)據(jù)塊。函數(shù)調(diào)用的一般形式為:

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

其中:buffer是一個指針,在fread函數(shù)中,它表示存放輸入數(shù)據(jù)的首地址,在fwrite函數(shù)中,它表示存放輸出數(shù)據(jù)的首地址。size

表示要讀寫的字節(jié)數(shù)。count

表示要讀寫的數(shù)據(jù)塊塊數(shù)(即count個size大的數(shù)據(jù)塊)。fileP表示文件指針。62計算機(jī)工程學(xué)院8.格式化讀寫函數(shù)fscanf和fprintf

fscanf函數(shù),fprintf函數(shù)與前面使用的scanf和printf

函數(shù)的功能相似,都是格式化讀寫函數(shù)。不同之處在于fscanf

函數(shù)和fprintf函數(shù)的讀寫對象不是鍵盤和顯示器,而是磁盤文件。函數(shù)的調(diào)用格式為:

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

fprintf(文件指針,格式字符串,輸出表列);要注意的是,當(dāng)在內(nèi)存和磁盤頻繁交換數(shù)據(jù)的情況下,最好不使用這兩個函數(shù),而使用fread和fwrite函數(shù)。63計算機(jī)工程學(xué)院9.文件的定位和測試(1)文件的定位上一節(jié)介紹的對文件的讀寫方式都是順序讀寫,即讀寫文件只能從頭開始,順序讀寫各個數(shù)據(jù)。但在實際問題中常要求只讀寫文件中某一指定的部分,也就是移動文件指針到需要讀寫的位置,再進(jìn)行讀寫,這種讀寫稱為隨機(jī)讀寫。實現(xiàn)隨機(jī)讀寫的關(guān)鍵是按要求移動文件指針,這稱為文件的定位。

rewind

函數(shù):調(diào)用形式為

rewind(文件指針);64計算機(jī)工程學(xué)院它的功能是把文件指針重新移到文件的開頭。此函數(shù)沒有返回值。

fseek

函數(shù):fseek函數(shù)用來移動文件指針,其調(diào)用形式為:

fseek(文件指針,位移量,起始點);其中:“文件指針”指向被移動的文件。“位移量”是指以“起始點”為基點,向前移動的字節(jié)數(shù)。要求位移量是long型數(shù)據(jù),以便在文件的長度大于64K時不會出問題。當(dāng)用常量表示

65計算機(jī)工程學(xué)院

位移量時,直接在末尾加后綴“L”。“起始點”表示從文件的什么位置開始計算位移量,規(guī)定的起始點有三種:文件首,當(dāng)前位置和文件尾。其表示方法如表7-2所示。表7-2文件指針三種起始點起始點表示符號數(shù)字表示文件首SEEK__SET0當(dāng)前位置SEEK__CUR1文件末尾SEEK__END266計算機(jī)工程學(xué)院

fseek函數(shù)一般用于二進(jìn)制文件,這是因為文本文件要進(jìn)行轉(zhuǎn)換,在計算位置的時候會出現(xiàn)錯誤。(2)文件檢測函數(shù)C語言中常用的文件檢測函數(shù)有以下幾個:●文件結(jié)束檢測函數(shù)feof()調(diào)用格式:feof(文件指針);功能:判斷文件是否處于文件結(jié)束位置,如文件結(jié)束,則返回值為1,否則為0。●讀寫文件出錯檢測函數(shù)ferror()調(diào)用格式:ferror(文件指針);67計算機(jī)工程學(xué)院功能:檢查文件在用各種輸入輸出函數(shù)進(jìn)行讀寫時是否出錯。如ferror返回值為0表示未出錯,否則表示有錯。●文件出錯標(biāo)志和文件結(jié)束標(biāo)志置0函數(shù)clearerr()調(diào)用格式:clearerr(文件指針);功能:用于清除出錯標(biāo)志和文件結(jié)束標(biāo)志,使它們?yōu)?值。68計算機(jī)工程學(xué)院

7.2.3技能訓(xùn)練

【實驗7-7】編寫程序,從鍵盤上輸入一系列字符,寫到磁盤文件file中,以#作為輸入的結(jié)束標(biāo)志,然后把文件中的內(nèi)容在屏幕上輸出。【指導(dǎo)】本實驗的功能是執(zhí)行了兩次磁盤文件操作:先用fputc函數(shù)把輸入的字符放在fileP指向的文件中,然后把文件中的內(nèi)容用fgetc函數(shù)逐個讀取,在屏幕上顯示。程序定義了文件指針fileP,先以寫方式打開文本文件file,并使fileP指向該文件。如打開文件出錯,給出提示并退出程序。輸入字符到文件中的循環(huán)是以輸入“#”作為循環(huán)結(jié)束的標(biāo)志;69計算機(jī)工程學(xué)院然后再以讀方式打開文本文件file,循環(huán)讀取文本文件的每一個字符,并顯示在屏幕上,并以EOF作為循環(huán)的結(jié)束標(biāo)志,也就是判斷是否讀到文件的結(jié)尾。每次文件操作結(jié)束后,都要用fclose函數(shù)關(guān)閉文件。

/*EX7_9.CPP*/#include<stdio.h>#include<conio.h>#include<stdlib.h>voidmain()70計算機(jī)工程學(xué)院

{ FILE*fileP; charcharC; if((fileP=fopen("file","w"))==NULL) { printf("不能打開文件\n"); exit(0); } printf(“請輸入字符:\n”); while((charC=getchar())!=’#’) {71計算機(jī)工程學(xué)院

fputc(charC,fileP); } fclose(fileP); if((fileP=fopen("file","r"))==NULL) { printf("不能打開文件\n"); exit(0); } printf("文件內(nèi)容為:\n"); charC=fgetc(fileP);72計算機(jī)工程學(xué)院

while(charC!=EOF) { putchar(charC); charC=fgetc(fileP); } fclose(fileP); }該程序首先打開當(dāng)前目錄中文件名為file的文件,然后從鍵盤上輸入字符并存儲到文件file

73計算機(jī)工程學(xué)院中,輸入完成后關(guān)閉文件file,最后再次打開文件file,并輸出文件file中的字符。圖7-13為該程序的一次運(yùn)行實例.圖7-13程序EX7_9運(yùn)行結(jié)果74計算機(jī)工程學(xué)院【實驗7-8】有兩個磁盤文件a1.txt和a2.txt,各存放若干行字母,今要求把這兩個文件中的信息按行交叉合并(即先是a1.txt的的第一行,接著是a2.txt中的第一行,然后是a1.txt的第二行,跟著是a2.txt的第二行,…),輸出到一個新文件a3.txt中去?!局笇?dǎo)】以讀方式打開磁盤文件a1.txt和a2.txt,然后依次讀取a1.txt和a2.txt的一行,交叉存入新文件a3.txt,因此可以通過3個循環(huán)語句實現(xiàn)。具體做法為:通過fgets函數(shù)分別獲得文件a1.txt和a2.txt中的每一行字符,分別賦值給字符數(shù)組str1和str2,然后將字符數(shù)組str1和75計算機(jī)工程學(xué)院

str2中的內(nèi)容依次寫入文件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計算機(jī)工程學(xué)院

{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計算機(jī)工程學(xué)院

{fputs(str1,fp3);}while(fgets(str2,255,fp2)!=NULL){fputs(str2,fp3);}/*charcharC;//以下注釋掉的代碼,為查看文件a1、a2、a3的內(nèi)容,以檢查運(yùn)行效果rewind(fp1);rewind(fp2);rewind(fp3);printf("a1文件內(nèi)容為:\n");78計算機(jī)工程學(xué)院charC=fgetc(fp1);while(charC!=EOF){putchar(charC);charC=fgetc(fp1);}printf("a2文件內(nèi)容為:\n");charC=fgetc(fp2);while(charC!=EOF){putchar(charC);charC=fgetc(fp2);}79計算機(jī)工程學(xué)院printf("a3文件內(nèi)容為:\n");charC=fgetc(fp3);while(charC!=EOF){putchar(charC);charC=fgetc(fp3);}*/fclose(fp1);fclose(fp2);fclose(fp3);}去掉上述代碼中的注釋符號,該程序的一次運(yùn)行實例如下圖7-14。80計算機(jī)工程學(xué)院圖7-14程序EX7_10運(yùn)行結(jié)果81計算機(jī)工程學(xué)院【實驗7-9】從鍵盤輸入兩個學(xué)生數(shù)據(jù),寫入一個文件中,再讀出這兩個學(xué)生的數(shù)據(jù)顯示在屏幕上?!局笇?dǎo)】該實驗需要一個數(shù)據(jù)結(jié)構(gòu)來存儲學(xué)生信息,因此需要定義一個學(xué)生結(jié)構(gòu)體。并將輸入后的學(xué)生信息寫入文件,再讀出該文件的內(nèi)容,顯示在屏幕上。每個學(xué)生的信息包含一組數(shù)據(jù),因此使用數(shù)據(jù)塊讀寫函數(shù)fread和fwrite來完成對文件的讀寫,程序如下。

/*EX7_11.CPP*/#include<stdio.h>82計算機(jī)工程學(xué)院#include<conio.h>#include<stdlib.h>structstu{ charname[10]; intnum; intage; charaddr[20];}stu_1[2],stu_2[2],*p,*q;voidmain(){83計算機(jī)工程學(xué)院 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計算機(jī)工程學(xué)院 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計算機(jī)工程學(xué)院本例程序定義了一個結(jié)構(gòu)stu,說明了兩個結(jié)構(gòu)數(shù)組stu_1和stu_2以及兩個結(jié)構(gòu)指針變量p和q。p指向stu_1,q指向stu_2。程序以讀寫方式打開二進(jìn)制文件“stu_list”,輸入二個學(xué)生數(shù)據(jù)之后,寫入該文件中,然后用rewind函數(shù)把文件內(nèi)部位置指針重新移到文件首,讀出兩個學(xué)生數(shù)據(jù)后,在屏幕上顯示。86計算機(jī)工程學(xué)院圖7-15程序EX7_11運(yùn)行結(jié)果【實驗7-10】用fscanf和fprintf函數(shù)完成實驗7-9的問題?!局笇?dǎo)】與函數(shù)fread和fwrite相比,fscanf和fprintf函數(shù)每次只能讀寫一個結(jié)構(gòu)數(shù)組元素,因此采用了循環(huán)語句來讀寫全部數(shù)組元素,程序87計算機(jī)工程學(xué)院如下。

/*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計算機(jī)工程學(xué)院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計算機(jī)工程學(xué)院 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計算機(jī)工程學(xué)院 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函數(shù)每次只能讀寫一個結(jié)構(gòu)數(shù)組元素,因此采用了循環(huán)語句來讀寫全部數(shù)組元素。還要注意指針變量p,q由于循環(huán)改變了它們的值,因此在程序中分別對它們重新賦予了數(shù)組的首地址。91計算機(jī)工程學(xué)院圖7-16程序EX7_12運(yùn)行結(jié)果【實驗7-11】在學(xué)生文件stu_list中讀出第二個學(xué)生的數(shù)據(jù)?!局笇?dǎo)】前兩個實驗對文件的讀取都是順序讀出,而該實驗只讀寫文件stu_list中某一指定部分的內(nèi)容。因此用函數(shù)fseek先將文件內(nèi)部的位置92計算機(jī)工程學(xué)院指針移動到需要讀寫的位置,然后再使用函數(shù)fread讀取指定數(shù)據(jù)。/*EX7_13.CPP*/#include<stdio.h>#include<conio.h>#include<stdlib.h>structstu{charname[10];intnum;93計算機(jī)工程學(xué)院intage;charaddr[20];}student,*p;main(){ FILE*fp;inti=1;p=&student;if((fp=fopen("stu_list","rb"))==NULL){printf("Cannotopenfilestrikeanykeyexit!");getch()();94計算機(jī)工程學(xué)院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);}該程序的一次運(yùn)行實例如下圖7-17。95計算機(jī)工程學(xué)院圖7-17程序EX7_13運(yùn)行結(jié)果96計算機(jī)工程學(xué)院

7.2.4拓展與練習(xí)

【練習(xí)1】利用本章的學(xué)習(xí)內(nèi)容實現(xiàn)簡單的文件加密。【指導(dǎo)】每次對原文中的一個字符進(jìn)行加密,再將加密后的這個字符存儲到密文,直到將原文中的每個字符做如上處理后,才結(jié)束該加密程序。具體做法為:首先通過鍵盤輸入加密密鑰,然后讀取原文中的每一個字符,與加密密鑰進(jìn)行異或操作,得到該字符的加密密文,然后將該加密密文存入密文中,直到處理完原文中的每個字符,程序如下。97計算機(jī)工程學(xué)院/*EX7_14.CPP*/#include<stdio.h>#include<conio.h>#include<stdlib.h>voidmain(){ FILE*originalfile,*Cipherfile; charcharC; intintCipher; intintN; printf("請輸入密鑰intN的值:");98計算機(jī)工程學(xué)院 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計算機(jī)工程學(xué)院 intCipher=(int)(charC)^intN; fputc((char)(intCipher),Cipherfile); charC=fgetc(originalfile); }fclose(Cipherfile);fclose(originalfile);}該程序?qū)崿F(xiàn)了較簡單對稱加密的一種算法。在C語言中,一個int型數(shù)據(jù)占2個字節(jié),因此該程序可以有65536個加密密鑰。現(xiàn)假設(shè)輸入加密密鑰1234,其執(zhí)行效果如圖7-18至圖7-20。100計算機(jī)工程學(xué)院圖7-18程序EX7_14運(yùn)行結(jié)果圖7-19程序EX7_14加密前原文內(nèi)容101計算機(jī)工程學(xué)院圖7-20程序EX7_14加密后密文內(nèi)容102計算機(jī)工程學(xué)院此外,該實例只是為了說明通過C語言中的位運(yùn)算與文件處理解決問題的方法。在實際中,加密算法要復(fù)雜得多,對它的處理相對也比較復(fù)雜。例如該程序可以使用不同的加密密鑰進(jìn)行多次加密,或者配合使用其他位運(yùn)算,對原文實現(xiàn)非對稱加密等方法,都可以增加密文的破解難度,以達(dá)到文件傳輸過程中的安全性。解密為加密的逆過程,因此解密程序可以作為課后練習(xí),由自己編程運(yùn)行。103計算機(jī)工程學(xué)院

7.2.5編程規(guī)范與常見錯誤

1.使用文件時忘記打開文件;2.用只讀方式打開,卻企圖向該文件輸出數(shù)據(jù);3.文件使用完,忘記關(guān)閉文件等錯誤。因此文件打開前,應(yīng)做到對文件的狀態(tài)進(jìn)行檢查。104計算機(jī)工程學(xué)院

7.2.6貫通案例之八

1.問題描述:在貫通案例七的基礎(chǔ)上實現(xiàn)學(xué)生成績管理系統(tǒng)的加載文件,保存文件兩個功能。2.編寫程序/*函數(shù)功能:保存學(xué)生記錄文件 函數(shù)參數(shù):結(jié)構(gòu)體指針head,指向存儲學(xué)生信息的結(jié)構(gòu)體數(shù)組的首地址 整型變量n,表示學(xué)生人數(shù) 整型變量m,表示考試科目函數(shù)返回值:無*/105計算機(jī)工程學(xué)院/*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計算機(jī)工程學(xué)院 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. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論