十年網(wǎng)站開(kāi)發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專業(yè)推廣+無(wú)憂售后,網(wǎng)站問(wèn)題一站解決
經(jīng)過(guò)上次的飛機(jī)游戲制作,使我感覺(jué)到C語(yǔ)言程序設(shè)計(jì),更加的有趣,也使我對(duì)這門(mén)課程有了更深的理解和認(rèn)識(shí)。這次我們學(xué)習(xí)了學(xué)習(xí)C語(yǔ)言操作文件永久保存數(shù)據(jù)和基于函數(shù)的結(jié)構(gòu)化大型程序的編寫(xiě)方法。這次的學(xué)習(xí)也比較上次來(lái)說(shuō)顯得有些復(fù)雜。

創(chuàng)新互聯(lián)專注于閬中網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供閬中營(yíng)銷型網(wǎng)站建設(shè),閬中網(wǎng)站制作、閬中網(wǎng)頁(yè)設(shè)計(jì)、閬中網(wǎng)站官網(wǎng)定制、微信小程序開(kāi)發(fā)服務(wù),打造閬中網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供閬中網(wǎng)站排名全網(wǎng)營(yíng)銷落地服務(wù)。
這次要做的是一個(gè)關(guān)于書(shū)本的管理系統(tǒng)??梢宰屛覀兏臃奖愕娜ダ贸绦虿檎視?shū)本存放的位置和一些基本的信息。
一、 C語(yǔ)言文件的操作
1、 文件操作的基本方法:
C語(yǔ)言將計(jì)算機(jī)的輸入輸出設(shè)備都看作是文件。例如,鍵盤(pán)文件、屏幕文件等.
你應(yīng)該還記得,向屏幕輸出一個(gè)信息,例如經(jīng)典的“HelloWorld!”是
#include.h>
int main()
{
printf("HelloWorld! \\n");
}
從鍵盤(pán)接收一個(gè)字符串然后顯示是
#include.h>
int main()
{
char a[10];
scanf("%s",&a);
printf("%s \\n",a);
}
那么,如果寫(xiě)一個(gè)字符串到一個(gè)文件中,是什么方式呢?顯示到屏幕上是默認(rèn)的輸出文件,如果是硬盤(pán)中的一個(gè)文件,首先要打開(kāi)一個(gè)文件,然后才能往里寫(xiě),那么就要告訴程序這個(gè)文件在什么地方,按照什么樣的方式打開(kāi)(讀、寫(xiě)、讀和寫(xiě)、添加、覆蓋等),然后打開(kāi)后要給這個(gè)打開(kāi)的文件一個(gè)符號(hào)(指針變量),表示后續(xù)的讀和寫(xiě)都是針對(duì)這個(gè)文件的,而不是到屏幕的,這個(gè)指針變量以后就代表了文件自身了。
定義一個(gè)代表文件的符號(hào)(指針變量)這樣的形式
FILE *fp;
其中FILE是固定的寫(xiě)法,后面的是指針變量名,可以隨意起。
這個(gè)時(shí)候fp還是一個(gè)空的指針變量,什么也沒(méi)有代表,類似一個(gè)倉(cāng)庫(kù)里的貨架的標(biāo)簽,什么也沒(méi)有寫(xiě)。
然后讓這個(gè)指針變量指向一個(gè)文件,就是打開(kāi)一個(gè)文件,然后讓這個(gè)指針變量指向這個(gè)打開(kāi)的文件,后續(xù)對(duì)這個(gè)指針變量的操作就都是對(duì)這個(gè)文件的操作了。
打開(kāi)文件的語(yǔ)句是
fopen(文件位置,打開(kāi)模式);
文件位置好理解,就是文件所在的位置,例如c://test.txt
打開(kāi)模式有幾種,
r(read): 讀
w(write): 寫(xiě)
a(append): 追加
t(text): 文本文件,可省略不寫(xiě)
b(banary): 二進(jìn)制文件
+: 讀和寫(xiě)
一般是rt+,也可以寫(xiě)成r+,和w+,就是讀和寫(xiě),能保留原來(lái)的內(nèi)容。
所以打開(kāi)C盤(pán)下my目錄中的文件c:\\my\\test.txt的語(yǔ)句是
fp=fopen("c://my/test.txt","r+");
注意文件夾符號(hào)同上面的不同。
這個(gè)時(shí)候如果打開(kāi)的文件出問(wèn)題的話,往一個(gè)空指針里面寫(xiě)東西是比較危險(xiǎn)的,很容易把系統(tǒng)弄崩潰了。所以在后續(xù)的讀寫(xiě)操作前,最好測(cè)試一下,打開(kāi)文件后這個(gè)文件指針fp是否還是空的,如果是空的話,就不能往下執(zhí)行了。所以語(yǔ)句變成了這樣
if((fp=fopen(" c://my/test.txt ","r+")) == NULL)
{
printf("文件沒(méi)有正確打開(kāi),不能往下執(zhí)行了. \\n");
exit(1);
}
完整的程序成了這樣
#include.h>
int main()
{
FILE *fp;
if((fp=fopen("c://my/test.txt","r+"))==NULL)
{
printf("文件沒(méi)有正確打開(kāi),不能往下執(zhí)行了. \\n");
return(1);
}
}
你會(huì)看到,程序報(bào)錯(cuò),因?yàn)闆](méi)有my這個(gè)目錄,所以你要在C盤(pán)下先建立一個(gè)my目錄,然后建立一個(gè)test.txt文件?;蛘吣愦蜷_(kāi)方式選擇寫(xiě)和讀,如果沒(méi)有目錄或者文件的話,程序會(huì)自動(dòng)幫你建一個(gè)文件。就是這樣
if((fp=fopen("c://my/test.txt","w+"))==NULL)
有時(shí)間自己可以百度一下C語(yǔ)言打開(kāi)文件的類型,功能非常豐富。
然后就可以用前面的輸入和輸出語(yǔ)句,向文件中寫(xiě)內(nèi)容了,同咱們上學(xué)期學(xué)的是一致的,就是在printf和scanf前面加f,成為fprint和fscanf,表示向文件輸出和從文件輸入,不是向屏幕輸出和從鍵盤(pán)輸入。
下面的程序?qū)崿F(xiàn)了從鍵盤(pán)輸入一個(gè)字符,然后寫(xiě)到文件中。
#include.h>
int main()
{
char a[20];
char b[20];
printf("請(qǐng)輸入一個(gè)字符串(小于20個(gè)字符),寫(xiě)到c://my/test.txt中 \\n");
scanf("%s",&a);
FILE *fp;
if((fp=fopen("c://my/test.txt","w+"))==NULL)
{
printf("文件沒(méi)有正確打開(kāi),不能往下執(zhí)行了. \\n");
return(1);
}
fprintf(fp,"%s",a);
fclose(fp);
}
執(zhí)行完后,你打開(kāi)文件看看,你寫(xiě)的字符是否寫(xiě)進(jìn)去了?
然后,你在記事本中在文件中寫(xiě)一個(gè)字符串,例如你的名字,然后用fscanf讀出來(lái),而不用在屏幕上輸入了。
#include.h>
int main()
{
char a[20];
FILE *fp;
if((fp=fopen("c://my/test.txt","r+"))==NULL)
{
printf("文件沒(méi)有正確打開(kāi),不能往下執(zhí)行了. \\n");
return(1);
}
fscanf(fp,"%s",&a);
printf("%s \\n",a);
fclose(fp);
}
讀取文件的時(shí)候有個(gè)指針,保證按照順序依次往下讀,如果讀到頭了想從頭再來(lái),類似看書(shū)一頁(yè)頁(yè)讀完了想到頭上重新操作,用函數(shù)rewind(fp)就可以了,如果想定位到某個(gè)位置,類似將書(shū)翻到某一頁(yè),用fseek(fp,偏移量,基準(zhǔn)),就是在基準(zhǔn)(0代表文件頭,1代表當(dāng)前位置,2代表文件尾)的基礎(chǔ)上便宜多少。
這就是基本的文件的讀寫(xiě)語(yǔ)句。有了文件的讀寫(xiě)后,才能進(jìn)行管理系統(tǒng)的開(kāi)發(fā),因?yàn)槟愕暮芏嘈畔⒁娣诺轿募胁判?,否則在程序中,關(guān)機(jī)后數(shù)據(jù)就沒(méi)有了。
2、 函數(shù)的應(yīng)用和結(jié)構(gòu)化程序設(shè)計(jì)
如果沒(méi)有班級(jí)的話,咱們?nèi)W(xué)生在一個(gè)班里面,可以想象管理會(huì)多么混亂。咱們想了一個(gè)辦法,把同學(xué)按照專業(yè)分到不用的班級(jí)中,這樣管理起來(lái)就方便多了,系里發(fā)通知等,只發(fā)到班長(zhǎng)就行了,由班長(zhǎng)向下傳達(dá),班級(jí)內(nèi)部更改活動(dòng)內(nèi)容,也跟其他班級(jí)沒(méi)有關(guān)系,自己關(guān)起門(mén)來(lái)修改就可以了。所以程序也是這樣,如果是把所有的代碼都放到一起,那跟全校所有的同學(xué)都在一個(gè)班級(jí)一樣,互相之間相互聯(lián)系,程序代碼短還沒(méi)有什么問(wèn)題,程序代碼量一多了,將非常難管理。所以按照功能,將不同的代碼放到一起,用大括號(hào)括起來(lái),然后給這段代碼起個(gè)名字表示,類似咱們班級(jí)的名字,然后還要設(shè)置上參數(shù),一遍使用這個(gè)函數(shù)的時(shí)候向里傳遞實(shí)際的值,類似一個(gè)加法的函數(shù),完成兩個(gè)數(shù)的相加,我們可以寫(xiě)成
myadd(int a, int b)
{
int c;
c=a+b;
return c;
}
myadd就是我們給這個(gè)函數(shù)起的名字,以便使用,a和b的作用接收調(diào)用者傳遞過(guò)來(lái)的數(shù),然后把接收的兩個(gè)數(shù)相加后返回,這個(gè)函數(shù)的值在調(diào)用后就是返回的值c,所以如果我們想算99+23等于多少,只要調(diào)用我們寫(xiě)好的函數(shù)
myadd(99,23),這個(gè)時(shí)候函數(shù)的值就是99+23了,如果把結(jié)果保存在變量d中,可以寫(xiě)成
d=myadd(99,23);
有了函數(shù),我們就可以把不同功能的代碼組織到一起,不僅自己方便,而且程序特別簡(jiǎn)單明了,便于修改,其他人寫(xiě)的函數(shù)我們還可以直接拿來(lái)用。
所以我們的這個(gè)學(xué)生信息管理系統(tǒng)形式就非常簡(jiǎn)單了,一共用到了三個(gè)函數(shù)
int main()
{
int i,sum;
pagedis();
check();
menu();
}
第一個(gè)是顯示歡迎頁(yè)面,第二個(gè)是驗(yàn)證用戶名和口令,第三個(gè)是顯示菜單,并根據(jù)用戶的輸入選擇執(zhí)行相應(yīng)的操作。
還有一些其他的函數(shù),分別是menu()菜單函數(shù)調(diào)用的子函數(shù)。
結(jié)構(gòu)話程序后大概的形式就是這樣
#include.h>
void pagedis();
void check();
void menu();
int main()
{
pagedis();
check();
menu();
}
void pagedis(){
printf("我是顯示歡迎界面的模塊,具體內(nèi)容還要再完善! \\n");
}
void check(){
printf("我是驗(yàn)證用戶合法性的模塊,具體內(nèi)容還要再完善! \\n");
}
void menu(){
printf("我是引導(dǎo)用戶執(zhí)行各個(gè)功能的模塊,具體內(nèi)容還要再完善! \\n");
}
這就是結(jié)構(gòu)化程序設(shè)計(jì),把功能放到函數(shù)中,下一步就可以集中精力,完善函數(shù)中的內(nèi)容。
源代碼
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
#include"conio.h"
#define PAGE 3
#define MAX 1000
#define N 5
int k=0;
/*結(jié)構(gòu)體類型*/
typedef struct
{ int num;/*學(xué)號(hào)*/
char name[20];/*姓名*/
char sex[5];/*性別*/
int age;/*年齡*/
char studentclass[20];/*班級(jí)*/
int dorm;/*宿舍號(hào)*/
}STUDENTS;
int read_file(STUDENTS stu[])
{FILE *fp;
int i=0;
if((fp=fopen("stu.txt","rt"))==NULL)
{printf("\n\n*****庫(kù)存文件不存在!請(qǐng)創(chuàng)");
return 0;
}
while(feof(fp)!=1)
{
fread(&stu[i],sizeof(STUDENTS),1,fp);
if(stu[i].num==0)
break;
else
i++;
}
fclose(fp);
return i;
}
void save_file(STUDENTS stu[],int sum)
{FILE*fp;
int i;
if((fp=fopen("stu.txt","wb"))==NULL)
{printf("寫(xiě)文件錯(cuò)誤!\n");
return;
}
for(i=0;i if(fwrite(&stu[i],sizeof(STUDENTS),1,fp)!=1) printf("寫(xiě)文件錯(cuò)誤!\n"); fclose(fp); } /*創(chuàng)建學(xué)生信息*/ int input(STUDENTS stu[]) { int i,x; for(i=0;i<1000;i++) { system("cls"); printf("\n\n 錄入學(xué)生信息 (最多%d個(gè))\n",MAX); printf(" ----------------------------\n"); printf("\n 第%d個(gè)學(xué)生",k+1); printf("\n 請(qǐng)輸入學(xué)生的學(xué)號(hào):"); scanf("%d",&stu[k].num); printf("\n 請(qǐng)輸入學(xué)生的姓名:"); scanf("%s",stu[k].name); printf("\n 請(qǐng)輸入學(xué)生的性別:"); scanf("%s",stu[k].sex); printf("\n 請(qǐng)輸入學(xué)生的年齡:"); scanf("%d",&stu[k].age); printf("\n 請(qǐng)輸入學(xué)生的班級(jí):"); scanf("%s",stu[k].studentclass); printf("\n 請(qǐng)輸入學(xué)生的宿舍號(hào):"); scanf("%d",&stu[k++].dorm); printf("\n 請(qǐng)按1鍵返回菜單或按0鍵繼續(xù)創(chuàng)建"); scanf("%d",&x); if(x) break; } return k; } /*刪除學(xué)生信息*/ void deletel(STUDENTS stu[]) { system("cls"); char Stuname2[20]; int i,j; printf("請(qǐng)輸入學(xué)生姓名:"); scanf("%s",Stuname2); printf("\n"); for(i=0;i if(strcmp(stu[i].name,Stuname2)==0) for(j=0;j<20;j++) stu[i].name[j]=stu[i+1].name[j]; k--; printf("刪除成功\n"); printf("按任意鍵加回車返回主菜單!"); scanf("%d",&i); getchar(); } /*打印學(xué)生信息*/ void output(STUDENTS stu[]) { system("cls"); int i; for(i=0;i printf("學(xué)號(hào):%d,姓名:%s,性別:%s,年齡:%d,班級(jí):%s,宿舍號(hào): %d\n",stu[i].num,stu[i].name, stu[i].sex,stu[i].age,stu[i].studentclass,stu[i].dorm); printf("按任意鍵加回車返回主菜單!"); scanf("%d",&i); getchar(); } /*查詢學(xué)生信息*/ void inquire(STUDENTS stu[]) { int i; int num; system("cls"); printf(" \n\n請(qǐng)輸入您要查找的學(xué)生的學(xué)號(hào)"); scanf("%d",&num); for(i=0;i if(num==stu[i].num) printf("\n\n\n學(xué)號(hào):%d,姓名:%s,性別:%s,年齡:%d,班級(jí):%s,宿舍號(hào): %d\n",stu[i].num,stu[i].name, stu[i].sex,stu[i].age,stu[i].studentclass,stu[i].dorm); printf("按任意鍵加回車返回主菜單!"); scanf("%d",&i); getchar(); } /*修改學(xué)生信息*/ void change(STUDENTS stu[]) { int num,i,choice; system("cls"); printf("\n\n\n 請(qǐng)輸入您要修改的學(xué)生的學(xué)號(hào)"); scanf("%d",&num); for(i=0;i { if(num==stu[i].num) printf("\n學(xué)號(hào):%d,姓名:%s,性別:%s,年齡:%d,班級(jí):%s,宿舍號(hào): %d\n",stu[i].num,stu[i].name, stu[i].sex,stu[i].age,stu[i].studentclass,stu[i].dorm); printf("\n\n\n ********請(qǐng)輸入您想要修改的數(shù)據(jù)********\n\n"); printf(" 1. 學(xué)號(hào)\n\n"); printf(" 2. 姓名\n\n"); printf(" 3. 性別\n\n"); printf(" 4. 年齡\n\n"); printf(" 5. 班級(jí)\n\n"); printf(" 6. 宿舍號(hào)\n\n"); printf(" 請(qǐng)選擇(1-6):"); scanf("%d",&choice); switch(choice) {case 1:{ printf("\n 請(qǐng)輸入你改的新學(xué)號(hào)"); scanf("%d",&stu[i].num); break; } case 2:{ printf("\n 請(qǐng)輸入你改的新姓名"); scanf("%s",stu[i].name); break; } case 3:{ printf("\n 請(qǐng)輸入你改的新性別"); scanf("%s",stu[i].sex); break; } case 4:{ printf("\n 請(qǐng)輸入你改的新年齡"); scanf("%d",&stu[i].age); break; } case 5:{ printf("\n 請(qǐng)輸入你改的新班級(jí)"); scanf("%s",stu[i].studentclass); break; } case 6:{ printf("\n 請(qǐng)輸入你改的新宿舍"); scanf("%d",&stu[i].dorm); break; } } printf("學(xué)號(hào):%d,姓名:%s,性別:%s,年齡:%d,班級(jí):%s,宿舍號(hào): %d\n",stu[i].num,stu[i].name, stu[i].sex,stu[i].age,stu[i].studentclass,stu[i].dorm); printf("按任意鍵加回車返回主菜單!"); scanf("%d",&i); break; } } /*學(xué)生宿舍信息統(tǒng)計(jì)*/ void sort(STUDENTS stu[]) { int i,j,n=1,x; system("cls"); int t; for(i=0;i for(j=i+1;j if(stu[i].dorm { t=stu[i].dorm; stu[i].dorm=stu[j].dorm; stu[j].dorm=t; t=stu[i].num; stu[i].num=stu[j].num; stu[j].num=t; } for(i=0;i printf("順序 學(xué)號(hào) 宿舍\n %d %d %d\n",n++,stu[i].num,stu[i].dorm); printf("按任意鍵加回車返回主菜單!"); scanf("%d",&x); getchar(); } void pagedis() { printf(" \n\n\n **********************************\n"); printf(" * *\n"); printf(" * *\n"); printf(" * *\n"); printf(" * 歡迎進(jìn)入學(xué)生宿舍信息管理系統(tǒng) *\n"); printf(" * *\n"); printf(" * *\n"); printf(" * *\n"); printf(" **********************************\n"); } void check() { char userName[5];/*用戶名*/ char userPWD[5];/*密碼*/ int i,sum; system("color 4E"); for(i = 1; i < 4; i++) { /*用戶名和密碼均為123;*/ printf(" 用戶名和密碼均為123\n\n"); printf("\n 請(qǐng)輸入您的用戶名:"); gets(userName); printf("\n 請(qǐng)輸入您的密碼:"); gets(userPWD); if ((strcmp(userName,"123")==0) && (strcmp(userPWD,"123")==0))/*驗(yàn)證用戶名和密碼*/ { printf("用戶名和密碼正確,顯示主菜單"); return; } else { if (i < 3) { printf("用戶名或密碼錯(cuò)誤,提示用戶重新輸入"); printf("用戶名或密碼錯(cuò)誤,請(qǐng)重新輸入!"); } else { printf("連續(xù)3次輸錯(cuò)用戶名或密碼,退出系統(tǒng)。"); printf("您已連續(xù)3次將用戶名或密碼輸錯(cuò),系統(tǒng)將退出!"); exit(1); } } } } void menu() { STUDENTS stu[20]; int choice,k,sum; sum=read_file(stu); if(sum==0) { printf("首先錄入基本庫(kù)存信息!按回車后進(jìn)入*****\n"); getch(); sum=input(stu); } do { system("cls"); printf("\n\n\n ********學(xué)生信息管理系統(tǒng)********\n\n"); printf(" 1. 創(chuàng)建學(xué)生信息\n\n"); printf(" 2. 打印學(xué)生信息\n\n"); printf(" 3. 查詢學(xué)生信息\n\n"); printf(" 4. 修改學(xué)生信息\n\n"); printf(" 5. 刪除學(xué)生信息\n\n"); printf(" 6. 學(xué)生宿舍信息順序\n\n"); printf(" 0. 退出系統(tǒng)\n\n"); printf(" 請(qǐng)選擇(0-6):"); scanf("%d",&choice); switch(choice) { case 1: k=input(stu); break;/*創(chuàng)建學(xué)生信息*/ case 2: output( stu) ; break;/*打印學(xué)生信息*/ case 3: inquire(stu); break;/*查詢學(xué)生信息*/ case 4: change(stu); break;/*修改學(xué)生信息*/ case 5: deletel(stu); break;/*刪除學(xué)生信息*/ case 6: sort(stu); break;/*學(xué)生宿舍信息順序*/ case 0: break; } }while(choice!=0); save_file(stu,sum); } int main() { int i,sum; pagedis(); check(); menu(); }
網(wǎng)站欄目:C語(yǔ)言學(xué)生宿舍管理系統(tǒng)
分享鏈接:http://www.jiaotiyi.com/article/iidgso.html