第9、10章-文件及其應(yīng)用、C綜合性程序設(shè)計(jì)案例分析_第1頁
第9、10章-文件及其應(yīng)用、C綜合性程序設(shè)計(jì)案例分析_第2頁
第9、10章-文件及其應(yīng)用、C綜合性程序設(shè)計(jì)案例分析_第3頁
第9、10章-文件及其應(yīng)用、C綜合性程序設(shè)計(jì)案例分析_第4頁
第9、10章-文件及其應(yīng)用、C綜合性程序設(shè)計(jì)案例分析_第5頁
已閱讀5頁,還剩162頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

高級語言程序設(shè)計(jì)高級語言程序設(shè)計(jì)——基于計(jì)算思維能力培養(yǎng)高級語言程序設(shè)計(jì)——基于計(jì)算思維能力培養(yǎng)第9章文件及其應(yīng)用主要內(nèi)容文件概述文件的打開和關(guān)閉文件檢測函數(shù)文件讀寫操作文件隨機(jī)讀寫本章思維導(dǎo)圖學(xué)生

文件信息的創(chuàng)建9.19.1引例——學(xué)生文件信息的創(chuàng)建例如,在命令行下執(zhí)行:8_5<stu.txt>out.txtStu.txt輸入輸出重定向文件概述9.29.2文件概述9.2.1流的概念在C語言中的每個串行輸入源和輸出目標(biāo)被稱為“流”。輸入流是一個串行數(shù)據(jù)源,可以為程序提供輸入數(shù)據(jù)輸出流是串行數(shù)據(jù)的目的地,可以接收程序的輸出。流充當(dāng)了程序和輸入輸出設(shè)備之間的橋梁,這使得程序在輸入輸出數(shù)據(jù)時可以采用統(tǒng)一的方式來工作,而不必去關(guān)注具體的物理設(shè)備是什么。<stdio.h>提供了3個標(biāo)準(zhǔn)流流名稱流含義默認(rèn)連接外設(shè)stdin標(biāo)準(zhǔn)輸入鍵盤stdout標(biāo)準(zhǔn)輸出屏幕stderr標(biāo)準(zhǔn)錯誤屏幕9.2.2文件的分類1、文本文件與二進(jìn)制文件

C語言的<stdio.h>支持兩種類型的文件:文本文件(也稱ASCII文件)和二進(jìn)制文件。在文本文件中,用字節(jié)來存儲字符,這使人們可以檢查或編輯文件。在二進(jìn)制文件中,字節(jié)不一定表示字符,有可能是某數(shù)值型數(shù)據(jù)的某些bit位。例如,假設(shè)有變量聲明語句: shortinta=32767;在二進(jìn)制文件中,變量a僅占2個字節(jié)的存儲空間,如圖9-3所示。圖9-31、文本文件與二進(jìn)制文件

圖9-4而把變量a的值存入到文本文件中則需要5個字節(jié)的存儲空間,如圖9-4所示。例如,假設(shè)有變量聲明語句: shortinta=32767;1、文本文件與二進(jìn)制文件

另外,文本文件還有以下特性:文本文件分為若干行。文本文件的每一行通常以一兩個特殊字符結(jié)尾,在Windows中,行末的標(biāo)記是回車符與換行符。文本文件可以包含一個特殊的“文件末尾”標(biāo)記。一些操作系統(tǒng)允許在文本文件的末尾使用一個特殊的字節(jié)作為標(biāo)記。在Windows中,標(biāo)記為'\x1a'(Ctrl+Z)。1、文本文件與二進(jìn)制文件

2、緩沖文件與非緩沖文件

C語言中可使用以下兩種文件系統(tǒng):緩沖文件系統(tǒng),又稱為標(biāo)準(zhǔn)文件系統(tǒng)或高級文件系統(tǒng)。是一種高效、方便且常用的文件系統(tǒng)。后面要學(xué)習(xí)的文件操作函數(shù)都是基于緩沖文件系統(tǒng)的。非標(biāo)準(zhǔn)緩沖文件系統(tǒng),又稱低級文件系統(tǒng)。該系統(tǒng)與機(jī)器有關(guān),節(jié)省內(nèi)存,執(zhí)行效率高,但是應(yīng)用難度大。圖9-5文件緩沖區(qū)工作原理9.2.3文件指針stdio.h中定義了文件結(jié)構(gòu)體類型FILE。typedefstruct{ shortlevel; /*緩沖區(qū)‘滿’或‘空’的程度*/ unsignedflags; /*文件狀態(tài)標(biāo)志*/ charfd; /*文件描述符*/ unsignedcharhold; /*如無緩沖區(qū)不讀字符*/ shortbsize; /*緩沖區(qū)的大小*/ unsignedchar*buffer; /*數(shù)據(jù)緩沖區(qū)的位置*/ unsignedchar*curp; /*指針當(dāng)前的指向*/ unsignedistemp; /*臨時文件指示器*/ shorttoken; /*用于有效性檢查*/}FILE; C語言中對流的訪問是通過文件指針實(shí)現(xiàn)的,文件指針的類型為FILE*。用文件指針表示特定的流具有標(biāo)準(zhǔn)的名字,如stdin、stdout和stderr等;我們可以根據(jù)程序需要聲明一些另外的文件指針。例如:FILE*fp1,*fp2;定義了兩個文件指針fp1和fp2??梢酝ㄟ^文件打開函數(shù)將文件指針連接到指定的文件上。文件的打開與關(guān)閉9.39.3.1文件的打開1、fopen函數(shù)打開文件要使用庫函數(shù)fopen(),其函數(shù)原型為:FILE*fopen(constchar*filename,constchar*mode);fopen函數(shù)返回一個文件指針。例如:fp=fopen("in.dat","r");fp=fopen("d:\\cprogram\\test.c","r");為何要用\\注意:當(dāng)打開的文件不存在或建立新文件時沒有訪問權(quán)限等將導(dǎo)致無法打開文件,此時fopen函數(shù)會返回空指針。因此打開文件后要測試fopen函數(shù)返回值以確保文件是否被正確打開。2、讀寫模式模式字符串含義"r"或"rt"打開文本文件用于讀"rb"打開二進(jìn)制文件用于讀"w"或"wt"打開文本文件用于寫(文件不需要存在)"wb"打開二進(jìn)制文件用于寫(文件不需要存在)"a"或"at"打開文本文件用于追加(文件不需要存在)"ab"打開二進(jìn)制文件用于追加(文件不需要存在)"r+"或"rt+"打開文本文件用于讀和寫,從文件頭開始"rb+"打開二進(jìn)制文件用于讀和寫,從文件頭開始模式字符串含義"w+"或"wt+"打開文本文件用于讀和寫(如果文件存在就覆蓋原文件)"wb+"打開二進(jìn)制文件用于讀和寫(如果文件存在就覆蓋原文件)"a+"或"at+"打開文本文件用追加方式進(jìn)行讀和寫"ab+"打開二進(jìn)制文件用追加方式進(jìn)行讀和寫2、讀寫模式9.3.2文件的關(guān)閉C語言使用fclose函數(shù)來關(guān)閉已打開的文件。其函數(shù)原型如下:intfclose(FILE*filename);其中filename是文件指針,指向已打開的文件。9.3.2文件的關(guān)閉文件檢測函數(shù)9.49.4.1檢測文件末尾函數(shù)feof()函數(shù)用來檢測文件讀寫位置指針是否已到文件末尾。feof()的調(diào)用格式為:feof(fp);fp是文件指針,如果文件讀寫位置指針已到文件末尾,則函數(shù)返回非0值(邏輯真);否則函數(shù)返回0值(邏輯假)。例如,我們常用下面的語句來控制文件讀寫:

while(!feof(fp))

文件讀/寫語句;9.4.1檢測文件末尾函數(shù)9.4.2檢測出錯函數(shù)ferror()函數(shù)可用來檢測輸入輸出函數(shù)的每次調(diào)用是否有錯,函數(shù)的調(diào)用格式是:ferror(fp)正常時函數(shù)返回0值,出錯時函數(shù)返回非值(邏輯真)。一般在調(diào)用輸入輸出函數(shù)后可調(diào)用該函數(shù),以檢查輸入輸出函數(shù)的引用是否正確。例如:

文件讀寫語句; if(ferror(fp)) printf("文件讀寫錯誤!\n");9.4.2檢測出錯函數(shù)文件的讀寫操作9.59.5.1字符讀/寫函數(shù)1、字符讀函數(shù)fgetc()該函數(shù)用來從文件讀取一個字符,其函數(shù)原型為:intfgetc(FILE*fp);從fp讀出一個字符,將位置指針指向下一個字符,若讀成功,則返回該字符;若讀到文件尾,則返回EOF。常見的用法:while(!feof(fp)) {ch=fgetc(fp); … }

對文本文件還可以用以下的形式來判斷文件是否已讀到文件末尾。while((ch=fgetc(fp))!=EOF) …9.5.1字符讀/寫函數(shù)2、字符寫函數(shù)fputc()該函數(shù)用來將一個字符寫入文件。其函數(shù)原型為:intfputc(intch,FILE*fp);其中,ch是字符常量或字符變量,fp是文件指針。該語句的功能是把字符ch寫入到fp所指向的文件中;如果函數(shù)執(zhí)行成功,則返回ch;否則,返回EOF。例如:fputc('A',fp);

將大寫字母'A'寫入fp指示的文件中。9.5.2字符讀/寫函數(shù)應(yīng)用實(shí)例【例9.1】編寫一個程序,將從鍵盤輸入若干行字符串存入9_1.txt文件,并將文件中的內(nèi)容重新讀出顯示到屏幕上(以'#'作為輸入結(jié)束標(biāo)志)?!痉治觥靠墒紫葘㈡I盤上輸入的若干文本行寫入文件,再重新以只讀方式打開文件,將其內(nèi)容讀出后顯示在屏幕上。#include<stdio.h>intmain(){charch;FILE*fp;

fp=fopen("9_1.txt","w"); //以寫方式打開文本文件if(fp!=NULL){printf("請輸入若干行文本,以#結(jié)束輸入:\n");while((ch=getchar())!='#')//循環(huán)寫入fputc(ch,fp);fclose(fp);}elseprintf("文件創(chuàng)建失??!\n");fp=fopen("9_1.txt","r"); //以讀方式打開文本文件if(fp!=NULL){printf("文件內(nèi)容是:\n");while(!feof(fp)) //循環(huán)讀出{ch=fgetc(fp);putchar(ch); //可用fputc(ch,stdout)代替putchar(ch)}fclose(fp); //關(guān)閉文件}elseprintf("文件打開失??!\n");return0;}請輸入若干行文本,以#結(jié)束輸入:

TeachyouhowtoreadCprograms↙TeachyouhowtowriteCprograms↙TeachyouhowtodebugCprograms#↙文件內(nèi)容是:TeachyouhowtoreadCprogramsTeachyouhowtowriteCprogramsTeachyouhowtodebugCprograms9.5.3字符串讀/寫函數(shù)函數(shù)fgets和fputs分別用于從指定的文件中讀出一個字符串和把一個字符串寫入指定的文件。1、字符串讀函數(shù)fgets()函數(shù)fgets可以從指定文件中讀入一行字符串并存入到字符數(shù)組中。其函數(shù)原型為:char*fgets(char*s,intn,FILE*fp);

例如,若字符數(shù)組s的大小為20,則:fgets(s,20,fp);

從fp指向的文件中讀取最大長度為19的字符串存入s。

利用這一特性,我們可以用:fgets(s,sizeof(s),stdin);

來限定從鍵盤輸入的字符串的大小,這比直接用gets(s)函數(shù)要安全,可以防止輸入數(shù)據(jù)過長而導(dǎo)致非法訪問內(nèi)存。2、字符串寫函數(shù)fputs()函數(shù)fputs可以將一個字符串寫入指定的文件,其函數(shù)原型為:intfputs(constchar*s,FILE*fp);9.5.4字符串讀/寫函數(shù)應(yīng)用實(shí)例【例9.2】從鍵盤輸入一行字符串:“TeachyouhowtodesigngoodCprograms”,將其追加到text01.txt文本中去。【分析】因要向text01.txt中追加信息,所以應(yīng)該將其打開方式設(shè)置為a。#include<stdio.h>#defineN80intmain(){chars[N];FILE*fp;

fp=fopen("text01.txt","a");if(fp!=NULL){printf("請輸入一行文本:\n");fgets(s,N,stdin); //從鍵盤輸入字符串fputs(s,fp); //寫入文件fclose(fp); //關(guān)閉文件}elseprintf("文件打開失??!\n");}9.5.5格式化讀/寫函數(shù)1、格式化讀函數(shù)fscanf()fscanf的函數(shù)原型為:intfscanf(FILE*fp,constchar*format,變量地址列表);如果函數(shù)執(zhí)行成功,則返回正確輸入項(xiàng)的個數(shù);若執(zhí)行失敗,則返回0。例:

fscanf(fp,"%s%d",name,&age);2、格式化寫函數(shù)fprintf()fprintf的函數(shù)原型為:intfprintf(FILE*fp,constchar*format,輸出項(xiàng)列表);例如:fprintf(fp,"%12s%6d",name,age);將字符串name和整型變量age的值存入fp指向的文件。9.5.6格式化讀/寫函數(shù)應(yīng)用實(shí)例【例9.3】為例8.5中的程序設(shè)計(jì)從文件讀數(shù)據(jù)的函數(shù)和將學(xué)生數(shù)據(jù)存盤的函數(shù)。(1)增加從文件讀數(shù)據(jù)函數(shù)intreadData(stuStrus[],char*filename),從文件filename中讀入學(xué)生信息,存入學(xué)生數(shù)組s,函數(shù)返回讀取的學(xué)生人數(shù);(2)增加函數(shù)voidsaveData(stuStrus[],char*filesname,intn),將學(xué)生信息存入filename文件。數(shù)據(jù)格式:可以通過feof函數(shù)來判斷對文件的讀寫是否到達(dá)文件末尾。/*@函數(shù)名稱:readData入口參數(shù):stuStrus[],char*filename@函數(shù)功能:從文件filename讀入學(xué)生信息存入s,返回正確讀取的學(xué)生人數(shù)*/intreadData(stuStrus[],char*filename){FILE*fp;fp=fopen(filename,"r");if(fp!=NULL){intn=0,i;while(!feof(fp)){fscanf(fp,"%s",s[n].id); //讀入準(zhǔn)考證號fscanf(fp,"%s",s[n].name); //讀入姓名for(i=0;i<4;i++) //讀入4門課程成績fscanf(fp,"%f",&s[n].score[i]);n++;}fclose(fp);returnn; //返回有效學(xué)生人數(shù)}elsereturn0;}/*@函數(shù)名稱:saveData入口參數(shù):stuStrus[]char*filename,intn@函數(shù)功能:學(xué)生信息存盤函數(shù)*/voidsaveData(stuStru*s,char*filename,intn){FILE*fp;inti,j;fp=fopen(filename,"w");if(fp!=NULL){for(i=0;i<n;i++,s++){fprintf(fp,"%-12s",s->id); //輸出準(zhǔn)考證號fprintf(fp,"%-12s",s->name); //輸出姓名for(j=0;j<4;j++) //輸出成績fprintf(fp,"%-8.2f",s->score[j]);fprintf(fp,"%-8.2f\n",s->total);//輸出總分}fclose(fp);//關(guān)閉文件}elseprintf("文件保存失敗!\n");}intmain(){stuStrus[N];intn;n=readData(s,"studata.txt"); //從文件讀數(shù)據(jù)sum(s,n); //求和quickSort(s,0,n-1); //按總分由高到低排序print(s,n); //輸出saveData(s,"9_3.txt",n); //存盤return0;}準(zhǔn)考證號姓名語文數(shù)學(xué)英語綜合總分-----------------------------------------------------------------------------110100105楊婷130.00132.00128.00256.00646.00110100104劉潔121.00105.00130.00250.00606.00110100102李科108.00130.00125.00241.00604.00110100101王曉東112.00120.00121.00230.00583.00110100103趙國慶99.0098.00101.00200.00498.009.5.7數(shù)據(jù)塊讀/寫函數(shù)1、數(shù)據(jù)塊讀函數(shù)fread()fread函數(shù)用于從文件中讀出一個數(shù)據(jù)塊,其函數(shù)原型為:unsignedfread(void*buffer,unsignedsize,unsignedcount,FILE*fp);fwrite函數(shù)用于向文件寫入一個數(shù)據(jù)塊,其函數(shù)原型為:unsignedfwrite(constvoid*buffer,unsignedsize,unsignedcount,FILE*fp);2、數(shù)據(jù)塊寫函數(shù)fwrite()例9.3中的saveData函數(shù)對每一個學(xué)生數(shù)據(jù),是采用逐個數(shù)據(jù)項(xiàng)的方式來輸出到文件中的,這種方式的優(yōu)點(diǎn)是文件中的數(shù)據(jù)按固定的格式呈現(xiàn),便于用戶用記事本直接瀏覽,但操作的效率較低。采用fwrite()函數(shù)一次性將學(xué)生結(jié)構(gòu)體數(shù)組的n個元素寫入文件具有較高的存取效率。但該函數(shù)寫入數(shù)據(jù)時是將內(nèi)存數(shù)據(jù)塊直接寫入文件,因此宜采用二進(jìn)制文件為宜。同時應(yīng)注意,用fwrite()寫入文件的數(shù)據(jù)應(yīng)該用fread()函數(shù)按相應(yīng)地格式來進(jìn)行讀取,才能正確的還原數(shù)據(jù)。9.5.8數(shù)據(jù)塊讀/寫函數(shù)應(yīng)用實(shí)例(1)wirteToFile函數(shù),采用fwrite函數(shù)保存學(xué)生數(shù)據(jù)至文件。(2)readFromFile函數(shù),采用fread函數(shù)從文件讀入學(xué)生數(shù)據(jù)至某學(xué)生結(jié)構(gòu)體數(shù)組,并將結(jié)果顯示到屏幕上。【例9.4】為例9.3的程序設(shè)計(jì)函數(shù):voidwriteToFile(stuStrus[],char*filename,intn){FILE*fp;fp=fopen(filename,"wb"); //打開文件if(fp!=NULL){ fwrite(s,sizeof(stuStru),n,fp); //寫文件 fclose(fp);}elseprintf("文件保存失?。n");}/*@函數(shù)名稱:readFromFile入口參數(shù):stuStrus[]char*filename@函數(shù)功能:從文件filename讀入學(xué)生信息存入s,返回正確讀取的學(xué)生人數(shù)*/intreadFromFile(stuStrus[],char*filename){FILE*fp;intn=0,k;fp=fopen(filename,"rb");//打開文件if(fp!=NULL){while(1){k=fread(s+n,sizeof(stuStru),1,fp);//讀取一條記錄if(k!=1)break;//未讀取成功表明文件已結(jié)束n++;}returnn; //返回成功讀取的記錄總數(shù)fclose(fp);}else{printf("讀取數(shù)據(jù)失??!\n"); return0;}}intmain(){stuStrus[N],t[N];intn;n=readData(s,"studata.txt"); //從文件讀數(shù)據(jù)sum(s,n); //求和quickSort(s,0,n-1); //按總分由高到低排序writeToFile(s,"9_4.dat",n); //存盤n=readFromFile(t,"9_4.dat"); //讀取數(shù)據(jù)存入數(shù)組tprint(t,n); //輸出學(xué)生數(shù)據(jù)return0;}文件的隨機(jī)讀寫9.69.6文件的隨機(jī)讀寫按讀寫方式分為:順序文件與隨機(jī)文件。順序文件是指只能按順序讀寫的文件,如存儲在磁帶上的文件就是順序文件。隨機(jī)文件是指可以隨機(jī)讀寫文件任意位置內(nèi)容的文件,如存儲在磁盤、DVD等介質(zhì)上的文件大部分都為隨機(jī)文件。9.6.1文件的定位文件定位有關(guān)的函數(shù):fseek函數(shù)ftell函數(shù)rewind函數(shù)1、fseek函數(shù)fseek函數(shù)的作用是使文件讀寫位置指針移動到所需要的位置,它的調(diào)用方式為:fseek(文件指針,位移量,起始點(diǎn));符號名值含義SEEK_SET0文件開頭SEEK_CUR1文件當(dāng)前位置SEEK_END2文件末尾例如,若fp為指向例9.4的學(xué)生排序結(jié)果文件(9_4.dat)的指針,則:fseek(fp,sizeof(stuStru)*2,SEEK_SET);

表示將文件讀寫位置指針從文件開頭向前移動2個記錄的位置,即定位在第3個學(xué)生記錄的起始位置。1、fseek函數(shù)fseek(fp,-sizeof(stuStru)*2,SEEK_END);表示將文件讀寫位置指針從文件末尾向后移動2個記錄的位置,即定位到倒數(shù)第2個學(xué)生記錄的起始位置。注意:fseek()函數(shù)一般用于二進(jìn)制文件的隨機(jī)讀寫。1、fseek函數(shù)2、ftell函數(shù)ftell()函數(shù)用于返回文件讀寫位置指針相對于文件頭的字節(jié)數(shù),其值為long類型,出錯時返回-1。其調(diào)用格式為:ftell(fp);例如:longpostion;if((postion=ftell(fp))==-1L) printf("Afileerrorhasoccurredat%ld.\n",postion);用于通知用戶文件出錯的位置。2、ftell函數(shù)3、rewind函數(shù)使用rewind()函數(shù)可使文件讀寫位置指針重新返回文件的開頭處。調(diào)用格式為:rewind(fp);9.6.2文件隨機(jī)讀寫應(yīng)用實(shí)例【例9.5】例9.4程序?qū)W(xué)生排序的數(shù)據(jù)存入了二進(jìn)制文件9_4.dat,編寫程序從文件中由后向前讀取學(xué)生數(shù)據(jù)輸出到屏幕上,并將其結(jié)果保存到二進(jìn)制文件9_5.dat?!痉治觥靠梢圆捎胒seek()函數(shù)實(shí)現(xiàn)從文件末尾向文件頭方向依次讀取數(shù)據(jù)存入內(nèi)存結(jié)構(gòu)體數(shù)組,之后調(diào)用print()函數(shù)輸出。/*@函數(shù)名稱:readFromFile入口參數(shù):stuStrus[],char*filename@函數(shù)功能:從文件filename讀入學(xué)生信息存入s,返回正確讀取的學(xué)生人數(shù)*/intreadFromFile(stuStrus[],char*filename){FILE*fp;intn=0,k;fp=fopen(filename,"rb");//打開文件if(fp!=NULL){fseek(fp,-sizeof(stuStru),SEEK_END);while(1){k=fread(s+n,sizeof(stuStru),1,fp);//讀取一條記錄if(k!=1)break;//未讀取成功表明文件已結(jié)束n++;

fseek(fp,-2*sizeof(stuStru),SEEK_CUR);}returnn;//返回成功讀取的記錄總數(shù)fclose(fp);}else{ printf("讀取數(shù)據(jù)失敗!\n"); return0; }}intmain(){stuStrus[N];intn;n=readFromFile(s,"9_4.dat");//讀取數(shù)據(jù)存入數(shù)組sprint(s,n); //輸出學(xué)生數(shù)據(jù)writeToFile(s,"9_5.dat",n); //將結(jié)果保存到9_5.datreturn0;}【例9.6】例9.5程序已將按總分遞增的學(xué)生數(shù)據(jù)存入二進(jìn)制文件9_5.dat中,編寫一個程序,將屬性為{"110100106","柯男",121,130,99,215,565}的學(xué)生數(shù)據(jù)追加到文件末尾,并重新讀取學(xué)生信息后輸出到屏幕上。【分析】因要追加記錄到文件中,且對該文件寫完之后需要讀取數(shù)據(jù),因此打開模式應(yīng)設(shè)置為ab+。添加記錄后使用rewind()函數(shù)將文件讀寫指針重新定位到文件頭。#include<stdio.h>#defineN10000structstudent{charid[10]; //準(zhǔn)考證號charname[9]; //姓名floatscore[4]; //大小為4的數(shù)組,分別存儲4門課程分?jǐn)?shù)floattotal; //總分};typedefstructstudentstuStru;intmain(){stuStrus={"110100106","柯男",121,130,99,215,565};stuStrut;FILE*fp;intk,j;fp=fopen("9_5.dat","ab+");

if(fp!=NULL){fwrite(&s,sizeof(s),1,fp); //將學(xué)生s寫入文件rewind(fp); //重新回到文件頭部printf("%-12s%-12s","準(zhǔn)考證號","姓名"); //輸出表頭printf("%-8s%-8s%-8s%-8s%-8s\n","語文","數(shù)學(xué)","英語","綜合","總分");printf("--------------------------------------------------------\n");

while(1){k=fread(&t,sizeof(t),1,fp); //讀取一條記錄if(k!=1)break; //未讀取成功表明文件已結(jié)束printf("%-12s",t.id); //輸出準(zhǔn)考證號printf("%-12s",); //輸出姓名for(j=0;j<4;j++) //輸出成績printf("%-8.2f",t.score[j]);printf("%-8.2f\n",t.total); //輸出總分} fclose(fp); //關(guān)閉文件}else printf("文件打開失敗!");return0;}準(zhǔn)考證號姓名語文數(shù)學(xué)英語綜合總分-------------------------------------------------------------------------------110100103趙國慶99.0098.00101.00200.00498.00110100101王曉東112.00120.00121.00230.00583.00110100102李科108.00130.00125.00241.00604.00110100104劉潔121.00105.00130.00250.00606.00110100105楊婷130.00132.00128.00256.00646.00110100106柯男121.00130.0099.00215.00565.00【例9.7】(選讀)編寫一個程序,將256色的bmp位圖順時針旋轉(zhuǎn)180度存到另一個文件?!痉治觥恳帉懺摮绦?,首先要了解256色bmp位圖格式。256色bmp位圖包括4個部分,一個位圖文件頭,一個位圖信息頭,一個色表和位圖數(shù)據(jù)本身。位圖文件頭包含關(guān)于這個文件的信息,如從哪里開始是位圖數(shù)據(jù)的定位信息。位圖信息頭含有關(guān)于這幅圖像的信息,例如以象素為單位的寬度和高度。色表中有圖像顏色的RGB值。這三部分共占用文件的前1078個字節(jié),之后的內(nèi)容為位圖數(shù)據(jù)。因此,可以先將源文件的前1078個字節(jié)復(fù)制到目標(biāo)文件,再將之后的文件內(nèi)容從后向前復(fù)制到目標(biāo)文件。從而實(shí)現(xiàn)圖像順序時針180度旋轉(zhuǎn)。#include<stdio.h>intmain(intargc,char*argv[]){inti;charc;FILE*fp1,*fp2;if(argc!=3)exit(1);fp1=fopen(argv[1],"rb");

fp2=fopen(argv[2],"wb");第一個命令行參數(shù)為源文件第二個命令行參數(shù)為目標(biāo)文件if(fp1==NULL||fp2==NULL)exit(1);for(i=0;i<1078;i++) //復(fù)制文件頭信息{c=fgetc(fp1);fputc(c,fp2);}

fseek(fp1,-1,SEEK_END);

將文件讀寫位置指針定位到最后一個字節(jié)將位圖信息從后向前復(fù)制到目標(biāo)文件從文件末尾向文件頭移動while(ftell(fp1)>1077) { c=fgetc(fp1); fputc(c,fp2);

fseek(fp1,-2,SEEK_CUR);

} fclose(fp1); fclose(fp2); return0;}編譯后產(chǎn)生9_7.exe文件,設(shè)當(dāng)前文件夾下存有如圖9-8所示的位圖文件(文件名為:rabbit.bmp)在命令行下輸入:>9_7rabbit.bmprabbit2.bmp利用位運(yùn)算

對文件數(shù)據(jù)加密9.79.7利用位運(yùn)算對文件數(shù)據(jù)加密9.7.1位運(yùn)算1、移位運(yùn)算a<<b的值是將a中的位左移b位后的結(jié)果。每次從a的左端移出一位,在a的右端補(bǔ)一個0。a>>b則是將a中的位右移b位的結(jié)果。如果a是無符號數(shù)或非負(fù)數(shù),則右移時會在a的左端補(bǔ)0。如果a是負(fù)值,其結(jié)果依賴于編譯器,一些編譯器會在左端補(bǔ)0,而有些則會保留補(bǔ)碼的符號位而補(bǔ)1。因此,考慮到程序的可移植性,最好僅對無符號數(shù)或字符進(jìn)行移位運(yùn)算。例如:unsignedshorta=56,b,c;初始時,a的值為(二進(jìn)制形式):執(zhí)行b=a<<2;語句后,b的值為:執(zhí)行c=a>>1;語句后,c的值為:2、按位求反、按位與、按位或與按位異或運(yùn)算按位求反、按位與、按位或與按位異或四個運(yùn)算符分別為:~、&、|和^。例如: unsignedshorta=19,b=67,c;初始時a與b的值分別為:執(zhí)行c=~a;后,c的值為:執(zhí)行c=a&b;后,c的值為:執(zhí)行c=a|b;后,c的值為:執(zhí)行a=a^b;后,a的值為:再次執(zhí)行a=a^b;后,a的值重新回到原值??梢?,將變量連續(xù)與同一個數(shù)進(jìn)行兩次異或運(yùn)算后,可以將該數(shù)還原。9.7.2數(shù)據(jù)文件加密實(shí)例【例9.7】編寫程序?qū)τ脩裘懊艽a進(jìn)行加密后存入文件,并模擬用戶登錄系統(tǒng)的驗(yàn)證過程。#include<stdio.h>#include<stdlib.h>#include<string.h>/*@函數(shù)名稱:set入口參數(shù):charusername[],charpassword[],char*filename@函數(shù)功能:設(shè)置系統(tǒng)密碼*/voidset(charusername[],charpassword[],char*filename){FILE*fp;fp=fopen(filename,"w");inti;charuser[11];charpass[7];strcpy(user,username);strcpy(pass,password);if(fp!=NULL){i=0;while(user[i]){user[i]=user[i]^0x5a;i++;}i=0;

username加密while(pass[i]){pass[i]=pass[i]^0xb4;i++;}fprintf(fp,"%s\n",user);fprintf(fp,"%s\n",pass);fclose(fp);}}password加密/*@函數(shù)名稱:readFile入口參數(shù):charusername[],charpassword[],char*filename@從文件中讀取用戶名與密碼*/voidreadFile(charusername[],charpassword[],char*filename){FILE*fp;inti;fp=fopen(filename,"r");if(fp!=NULL){ fscanf(fp,"%s",username); fscanf(fp,"%s",password); i=0;while(username[i]){username[i]=username[i]^0x5a;i++;}i=0;while(password[i]){password[i]=password[i]^0xb4;i++;}

還原用戶名還原用戶密碼 fclose(fp);}}/*

@函數(shù)名稱:verify入口參數(shù):charusername[],charpassword[]@校驗(yàn)用戶名與密碼,最多允許用戶嘗試三次*/intverify(charusername[],charpassword[]){charuser[11];charpass[7];intcount=0;do{printf("Username:");gets(user);printf("Password:");gets(pass);if(strcmp(username,user)==0&&strcmp(password,pass)==0)return1; //驗(yàn)證成功count++;system("cls"); //清除屏幕printf("Usernameorpassworderror!");printf("Youhave%dchances:\n",3-count);}while(count<3);return0; //驗(yàn)證失敗}intmain(){intk,n;charusername[11],password[7];set("student","123456","user.txt"); readFile(username,password,"user.txt"); k=verify(username,password);if(k==1) printf("success!\n");elseprintf("fail!\n");return0;}設(shè)置初始用戶名與密碼讀用戶名與密碼實(shí)際系統(tǒng)中,用戶輸入的密碼不應(yīng)在屏幕上直接顯示出來,一般用*來代替,請思考如何改進(jìn)例中的驗(yàn)證程序?提示:ch=getch()函數(shù)調(diào)用能將鍵盤輸入的字符返回給ch,且輸入的字符在屏幕上不回顯學(xué)習(xí)本章后應(yīng)達(dá)到以下要求:(1)理解流的基本概念和文件的分類。(2)了解二進(jìn)制文件與文本文件的區(qū)別。(3)掌握文件的打開與關(guān)閉操作。(4)掌握文件檢測函數(shù)的使用。本章小結(jié)(5)熟練掌握文件的讀寫函數(shù)的使用方法及其應(yīng)用,包括字符讀/寫函數(shù),字符串讀/寫函數(shù),格式化讀/寫函數(shù),數(shù)據(jù)塊讀/寫函數(shù)。(6)掌握文件的隨機(jī)讀寫及其應(yīng)用。(7)了解利用位運(yùn)算進(jìn)行數(shù)據(jù)加密的方法。本章小結(jié)實(shí)驗(yàn)九1.編寫一個程序,將9_1.c文件內(nèi)容顯示到屏幕上。2.編寫一個函數(shù)intmycopy(char*file1,char*file2),實(shí)現(xiàn)將文本文件file1復(fù)制到文本文件file2,若復(fù)制成功函數(shù)返回1,否則返回0,請編寫main函數(shù)進(jìn)行測試。3.學(xué)生信息存儲在9_4.dat文件中(例9.4程序的運(yùn)行結(jié)果文件),編寫程序根據(jù)輸入的準(zhǔn)考證號,查詢學(xué)生的考試成績信息后輸出。實(shí)驗(yàn)九4.學(xué)生信息存儲在9_4.dat文件中(例9.4程序的運(yùn)行結(jié)果文件),編寫程序根據(jù)輸入的準(zhǔn)考證號,刪除相應(yīng)學(xué)生記錄。5.試編寫一個程序,將256色的bmp位圖順時針旋轉(zhuǎn)180°存到另一個文件。高級語言程序設(shè)計(jì)——基于計(jì)算思維能力培養(yǎng)第10章C綜合性程序設(shè)計(jì)案例分析軟件開發(fā)過程概述1主要內(nèi)容圖書管理系統(tǒng)案例分析2綜合課程設(shè)計(jì)選題3軟件開發(fā)過程

概述10.11、軟件危機(jī)與軟件工程隨著軟件規(guī)模的擴(kuò)大,最終出現(xiàn)了一堆問題:程序質(zhì)量低下,錯誤頻出,進(jìn)度延誤,軟件成本日益增長……更嚴(yán)重的是,許多程序因代碼缺少相關(guān)文檔,最終成為不可維護(hù)軟件產(chǎn)品,這些問題最終導(dǎo)致“軟件危機(jī)”。1968年北大西洋公約組織的計(jì)算機(jī)科學(xué)家在聯(lián)邦德國召開國際會議,討論“軟件危機(jī)”問題,在這次會議上正式提出并使用了“軟件工程”的概念,一門新的工程學(xué)科就此誕生。1、軟件危機(jī)與軟件工程軟件工程是指導(dǎo)計(jì)算機(jī)軟件開發(fā)和維護(hù)的一門工程學(xué)科。它采用工程的概念、原理、技術(shù)和方法來開發(fā)與維護(hù)軟件,把經(jīng)過時間考驗(yàn)而證明正確的管理技術(shù)和當(dāng)前能夠得到的最好的技術(shù)方法結(jié)合起來,以經(jīng)濟(jì)地開發(fā)出高質(zhì)量的軟件并有效地維護(hù)它。1、軟件危機(jī)與軟件工程2、軟件工程方法學(xué)目前,使用得最廣泛的軟件工程方法學(xué),分別是傳統(tǒng)方法學(xué)和面向?qū)ο蠓椒▽W(xué)。傳統(tǒng)方法學(xué)也稱為生命周期方法學(xué)。它采用結(jié)構(gòu)化技術(shù)(結(jié)構(gòu)化分析、結(jié)構(gòu)化設(shè)計(jì)和結(jié)構(gòu)體實(shí)現(xiàn))來完成軟件開發(fā)的各項(xiàng)任務(wù),并使用適當(dāng)?shù)能浖ぞ呋蜍浖こ汰h(huán)境來支持結(jié)構(gòu)化技術(shù)的運(yùn)用。3、軟件生命周期軟件規(guī)格描述的主要任務(wù)是解決“做什么”的問題。軟件規(guī)格描述通常進(jìn)一步劃分成三個階段:即問題定義、可行性研究和需求分析。軟件開發(fā)的主要任務(wù)是解決“如何做”的問題,即設(shè)計(jì)和實(shí)現(xiàn)在前一個階段定義的軟件,它通常由下述三個階段組成:總體設(shè)計(jì)、詳細(xì)設(shè)計(jì)、編碼實(shí)現(xiàn)。軟件確認(rèn)的主要任務(wù)是“確認(rèn)實(shí)現(xiàn)的系統(tǒng)滿足用戶的要求”,即依據(jù)規(guī)格說明來測試所實(shí)現(xiàn)的軟件。軟件測試包括單元測試、集成測試、系統(tǒng)測試等。通常單元測試合并在編碼實(shí)現(xiàn)階段進(jìn)行。3、軟件生命周期軟件維護(hù)的主要任務(wù)是使軟件持久地滿足用戶的需要。具體地說,當(dāng)軟件在使用過程中發(fā)現(xiàn)錯誤時應(yīng)該加以改正;當(dāng)環(huán)境改變時應(yīng)該修改軟件以適應(yīng)新的環(huán)境;當(dāng)用戶有新的要求時應(yīng)該及時改進(jìn)軟件以滿足用戶的需求。3、軟件生命周期(1)問題定義問題定義階段必須明確的是解決的問題是什么。通過問題定義階段的工作,提出關(guān)于問題性質(zhì)、工程目標(biāo)和規(guī)模的書面報(bào)告,最終的目標(biāo)是得出一份開發(fā)設(shè)計(jì)人員與客戶兩方都滿意的文檔。(2)可行性研究這個階段要明確在成本和時間的限制條件下,上一個階段所確定的問題是否有行得通的解決辦法。在客戶的配合下,由分析員提出解決問題的侯選方案,然后對每個方案從技術(shù)、經(jīng)濟(jì)、法律和操作等方面進(jìn)行可行性研究。其結(jié)果是客戶做出是否繼續(xù)進(jìn)行這項(xiàng)工程的決定的重要依據(jù)。這個階段的任務(wù)主要是明確為了解決這個問題,目標(biāo)系統(tǒng)必須做什么。為此,分析員要通過各種途徑與用戶溝通,獲取他們的真實(shí)需求,并通過建模技術(shù)來表達(dá)這些需求。(3)需求分析在需求分析階段確定的系統(tǒng)邏輯模型是以后設(shè)計(jì)和實(shí)現(xiàn)目標(biāo)系統(tǒng)的基礎(chǔ),必須準(zhǔn)確完整地體現(xiàn)用戶的要求。這個階段的一項(xiàng)重要任務(wù),是用正式文檔準(zhǔn)確地記錄對目標(biāo)系統(tǒng)的需求,這份文檔通常稱為規(guī)格說明書。(3)需求分析(4)總體設(shè)計(jì)總體設(shè)計(jì)又稱為概要設(shè)計(jì),這個階段的主要任務(wù)是確定系統(tǒng)的架構(gòu),即給出軟件的體系結(jié)構(gòu)。(5)詳細(xì)設(shè)計(jì)詳細(xì)設(shè)計(jì)的任務(wù)是把解決問題的方法具體化,也就是具體回答:“應(yīng)該怎樣具體地實(shí)現(xiàn)這個系統(tǒng)?”這個階段的任務(wù)還不是編寫程序,而是設(shè)計(jì)出程序的詳細(xì)規(guī)格說明。(6)編碼和單元測試這個階段的關(guān)鍵任務(wù)是寫出正確的容易理解、容易維護(hù)的程序模塊。測試是在認(rèn)為程序能工作的情況下,為發(fā)現(xiàn)其問題而進(jìn)行的一整套確定的系統(tǒng)化的實(shí)驗(yàn),編碼時應(yīng)對所完成的功能模塊進(jìn)行單元測試,以保證模塊能被正確地調(diào)用。(7)綜合測試這個階段的關(guān)鍵任務(wù)是通過種種類型的測試使軟件達(dá)到預(yù)定的要求。最基本的是集成測試和驗(yàn)收測試。所謂集成測試是根據(jù)設(shè)計(jì)的軟件結(jié)構(gòu),把經(jīng)過單元測試檢驗(yàn)的模塊按某種策略裝配起來,在裝配的過程中對程序進(jìn)行必要的測試。而驗(yàn)收測試則是按照規(guī)格說明書的要求,由用戶對目標(biāo)系統(tǒng)進(jìn)行驗(yàn)收。(8)軟件維護(hù)這個階段的任務(wù)是通過各種必要的維護(hù)活動使系統(tǒng)持久地滿足用戶的要求。基于用戶角色的圖書管理系統(tǒng)

案例分析10.210.2.1問題描述與需求分析某學(xué)校擬建立一個小型的圖書管理程序(學(xué)生人數(shù)不超過1000人,圖書數(shù)目不超過5000冊),實(shí)現(xiàn)對圖書的入庫、圖書查詢、舊書的刪除;創(chuàng)建用戶、查詢用戶、刪除用戶;借書、還書、續(xù)借;修改用戶密碼、系統(tǒng)備份等功能。要求以文件的方式保存用戶、圖書及借書信息。(1)要求系統(tǒng)提供系統(tǒng)管理員、圖書管理員、學(xué)生和教師四種不同的角色的權(quán)限管理。不同角色用戶登錄系統(tǒng)后擁有不同的權(quán)限。(2)系統(tǒng)管理員擁有“瀏覽用戶”、“添加用戶”、“刪除用戶”、“瀏覽圖書”、“添加圖書”、“刪除圖書”、“修改密碼”和“系統(tǒng)備份”等功能。功能需求:(3)圖書管理員擁有“圖書查詢”、“用戶借書信息查詢”、“借書”、“還書”、“按當(dāng)前借書量排序”和“修改登錄密碼”等功能。(4)學(xué)生擁有“圖書查詢”、“查詢本人借書書目”、“續(xù)借”、

溫馨提示

  • 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

提交評論