SCAU 高程綜合實驗:檔案操作與字元處理
SCAU 高程綜合實驗:檔案操作與字元處理
在當前目錄中存在檔名為"case1.in"(其中case後為數字1,不是字母l,寫錯提交後會判錯)的文字檔案,
其內容為一篇英文文章(以EOF作為結束標誌)。現要求讀取該文字檔案內容,統計文章中每個單詞出現的次數,
並輸出出現次數最多的前5個單詞及其出現次數(按出現次數由多到少的順序輸出,次數相同時按字典順序輸出,
不足5個單詞時,按序輸出全部單詞)。程式中注意如下細節:
(1) 空格、標點符號與回車符起到分隔單詞的作用。
(2) 文章一行的末尾可能有連字元,出現連字元時,該行最末的字串與下行最先出現的字串構一個單詞;
(3) 名詞縮寫算一個單詞;
(4) 數字不算單詞;
(5) 單詞不區分大小寫;
(6) 輸出時單詞全使用小寫;
#include “stdio.h”
#include “math.h”
#include “string.h”
#include “stdlib.h”
main()
{
_______________________
}
輸入格式
檔案case1.in中一篇英文文章,包含多段文字,單詞數不超過10000,每個單詞不超過20個字元
輸出格式
按題意輸出答案
輸入樣例
(如case1.in內容如下)
I am a student. My school is SCAU. It is a beau-
tiful university. I like it.
輸出樣例
a 2
i 2
is 2
it 2
am 1
解題思路分析:
按照解題順序,分析一下幾個重要的點:
第一個考點是檔案操作,檔案的開啟關閉和讀寫。題目中說掃描單詞,又由於有字串的特殊要求,所以使用fscanf有點小困難,還是使用fgetc逐字掃描、判斷。
第二個考點是單詞的判斷,也是這道題的核心,這個和前面oj上一題對單詞的判斷讀寫幾乎相同,只是多了個連字元的問題。當掃描到有單詞結束的符號(空格、標點等),打上標記,有連字元+換行的話,另作標記。
第三個考點是字串的存放以及字串的排序,當然其中也不可避免的有string庫中函式的運用。由於掃描完單詞後便存入陣列,自然要用到字串陣列,其中也變相的考察了學生地址(指標)的概念。排序的話自然是字典序,由於能力有限,使用冒泡+strcpy進行排序。
下面貼一下我的程式碼(含詳註)。
#include "stdio.h"
#include "math.h"
#include "string.h"
#include "stdlib.h"
char sto[10005][25];//字串陣列,無重複
int num=0;//字串陣列下標
int count[10005]; //每個單詞出現的次數
int isalpha(char ch) //判斷是否為字母(函式庫裡竟然沒有isalpha)
{
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) return 1;
else return 0;
}
int repeat(char *s)//判斷單詞是否重複
{
int i;
for(i=0;i<num;i++)
{
if(!strcmp(sto[i],s))//查重
{if(i==0) return 20000;else return i;}//查到重複的單詞,則返回單詞第一次出現的下標
}
return 0;//沒查到,則返回0
}
main()
{
FILE *fp;
int i,j=0,k;
char ch;
int endflag=0,lianflag=0,enter=0;
for(i=0;i<10005;i++) count[i]=1;//計數器初始化為1
fp=fopen("case1.in","r+");//開啟檔案
if(fp==NULL) {printf("ERROR");return 0;}
while((ch=fgetc(fp))!=EOF)//由於有連字元,用fscanf有點困難,所以開始逐字掃描操作,
{
if(isalpha(ch)&&ch>='A'&&ch<='Z') ch+=32;
if(isalpha(ch)&&endflag&&!lianflag&&!enter) {enter=0;endflag=0;lianflag=0;j=0;num++;sto[num][j++]=ch;}//新單詞的情況,更新連字元、回車、單詞結束的標記,建立新一行陣列記錄下一個單詞
else if(isalpha(ch)&&endflag==0&&!lianflag&&!enter) {enter=0;lianflag=0;sto[num][j++]=ch;}//同一個單詞的情況,即單詞續寫
else if(ch==' '||(lianflag==0&&ch=='\n')||((ch!='-')&&((ch>=32&&ch<=47)||(ch>=49&&ch<=64)||(ch>=91&&ch<=96)||(ch>=123&&ch<=126))))//單詞結束,檢索到符號、換行,就換單詞
{
enter=0;endflag=1;lianflag=0;
int p=0;
if(p=repeat(sto[num])) {if(p==20000) p=0;memset(sto[num],0,sizeof(sto[num]));num--;count[p]++;}
}
else if(isalpha(ch)&&lianflag&&!enter)//有連字元但無回車的特殊情況,算新單詞的出現,也標誌著連字元前一個單詞的結束,對前一個單詞進行查重計數,然後進行新單詞建立的操作
{int p=0;
if(p=repeat(sto[num])) {if(p==20000) p=0;memset(sto[num],0,sizeof(sto[num]));num--;count[p]++;}
enter=0;endflag=0;lianflag=0;j=0;num++;sto[num][j++]=ch;
}
else if(ch=='-'&&endflag==0) {enter=0;lianflag=1;}//檢索到連字元標記一下
else if(ch=='\n') {enter=1;}//檢索到換行標記一下
else if(lianflag&&isalpha(ch)&&!endflag&&enter) {enter=0;lianflag=0;sto[num][j++]=ch;}//有連字元+回車的情況,是原來的單詞,進行單詞的續寫
else {endflag=1;lianflag=0;if(repeat(sto[num])) {memset(sto[num],0,sizeof(sto[num]));num--;count[repeat(sto[num])]++;}} //其餘情況(包括數字)算作無單詞,進行標記的清除
}
fclose(fp);//檔案掃描結束,關閉檔案
char t[25];//下面將用到冒泡,建立第三方變數
int t2=0;//同理,計數器也要用到冒泡
for(i=0;i<num-1;i++)//將字串陣列按照字典序排序,使用氣泡排序
for(j=0;j<num-1-i;j++)
if(strcmp(sto[j],sto[j+1])>0)
{memset(t,0,sizeof(t));strcpy(t,sto[j]);t2=count[j];strcpy(sto[j],sto[j+1]);count[j]=count[j+1];strcpy(sto[j+1],t);count[j+1]=t2;}
int p=0;//掃描次數前五的單詞,如果不足五個就直接return 0
int max1=0,max2=0,max3=0,max4=0,max5=0; //由於只有五個,就不對次數進行排序了,直接比較依次求最多次數就好,比完把最多的次數清零
for(i=0;i<=num;i++) if(max1<count[i]) {p=i;max1=count[i];}
count[p]=0;
printf("%s %d\n",sto[p],max1);
for(i=0;i<=num;i++) if(max2<count[i]) {p=i;max2=count[i];}
if(max2==0) return 0;
else
{
count[p]=0;
printf("%s %d\n",sto[p],max2);
}
for(i=0;i<=num;i++) if(max3<count[i]) {p=i;max3=count[i];}
if(max3==0) return 0;
else
{
count[p]=0;
printf("%s %d\n",sto[p],max3);
}
for(i=0;i<=num;i++) if(max4<count[i]) {p=i;max4=count[i];}
if(max4==0) return 0;
else
{
count[p]=0;
printf("%s %d\n",sto[p],max4);
}
for(i=0;i<=num;i++) if(max5<count[i]) {p=i;max5=count[i];}
if(max5==0) return 0;
else
{
count[p]=0;
printf("%s %d\n",sto[p],max5);
}
return 0;
}
總結與心得:
綜合性實驗主要考查本學期c語言所學語法的綜合運用,靈活多變,思維量不大,實驗過程中細節和注意點較多。
儘管實驗大體思路清晰,但是在我的實踐過程並不是一帆風順。一開始沒有注意題目中連字元的規定,用了fscanf,看到測試資料t-t-t-t人傻了(這貨算4個單詞???),然後從零開始。很多知識點的細節沒徹底瞭解,也增添了我程式中的小bug。
通過本次實驗,我明白了平時學習知識,除了重點練習知識點主體部分,許多細節和注意點也要多多留意。題目先看清看完整,大體思路想明白寫清楚,再動手敲程式碼。有錯就改,改錯也是學知識不可或缺的一個環節,也是完善知識的一個過程,許多問題也是在上機實踐過程中才發現自己不會寫,然後通過搜尋引擎或者和小夥伴、老師的討論交流,去補上自己知識層面的漏洞或者改善自己程式碼。
相關文章
- 字元編碼與檔案處理字元
- 實驗--檔案操作
- Go檔案操作綜合指南Go
- 含有特殊字元的資料檔案處理字元
- 處理檔名內含有特殊字元的檔案 (轉)字元
- Python批處理:檔案操作Python
- 07 Windows批處理之檔案操作Windows
- 實時流處理與分散式儲存過程中對檔案的操作分散式儲存過程
- C++ 字元處理函式(cctype標頭檔案)C++字元函式
- 資料匯入與預處理實驗二---json格式檔案轉換JSON
- windows刪除檔案的批處理操作Windows
- IO流之 檔案操作字元流字元
- django-驗證碼/靜態檔案處理Django
- C中檔案基本讀寫操作(單字元,多字元)字元
- 3.python檔案操作及異常處理Python
- [R]檔案處理
- bat處理檔案BAT
- bat檔案處理BAT
- GC機制+字元編碼+檔案操作GC字元
- shell 字元處理字元
- Python中檔案I/O高效操作處理的技巧Python
- C檔案與檔案的操作
- Linux學習之檔案處理命令(二)目錄處理命令 && 檔案處理命令Linux
- window 批處理檔案
- python處理檔案Python
- Go xml檔案處理GoXML
- python檔案處理Python
- python 檔案處理Python
- Python 檔案處理Python
- JAVA ZIP 處理檔案Java
- 批處理檔案命令
- 檔案處理函式函式
- Windows批處理檔案Windows
- bat批處理檔案BAT
- 個人實驗程式碼記錄 | 數字影像處理實驗3·影像直方圖與均衡化處理直方圖
- 字元處理函式字元函式
- tr命令“字元”處理字元
- day07.檔案操作/綜合應用【Python教程】Python