c語言練手專案(一)
阿新 • • 發佈:2019-02-05
統計檔案的字元數、單詞數以及總行數,包括:
- 每行的字元數和單詞數
- 檔案的總字元數、總單詞數以及總行數
注意:
- 空白字元(空格和tab縮排)不計入字元總數;
- 單詞以空格為分隔;
- 不考慮一個單詞在兩行的情況;
- 限制每行的字元數不能超過1000。
請先看程式碼:
- #include <stdio.h>
- #include <string.h>
- int *getCharNum(char *filename, int *totalNum);
- int main(){
- char filename[30];
- // totalNum[0]: 總行數 totalNum[1]: 總字元數 totalNum[2]: 總單詞數
- int totalNum[3] = {0, 0, 0};
- printf("Input file name: ");
- scanf("%s", filename);
- if(getCharNum(filename, totalNum)){
- printf("Total: %d lines, %d words, %d chars\n", totalNum[0], totalNum[2], totalNum[1]);
- }else{
- printf("Error!\n");
- }
- return 0;
- }
- /**
- * 統計檔案的字元數、單詞數、行數
- *
- * @param filename 檔名
- * @param totalNum 檔案統計資料
- *
- * @return 成功返回統計資料,否則返回NULL
- **/
- int *getCharNum(char *filename, int *totalNum){
- FILE *fp; // 指向檔案的指標
- char buffer[1003]; //緩衝區,儲存讀取到的每行的內容
- int bufferLen; // 緩衝區中實際儲存的內容的長度
- int i; // 當前讀到緩衝區的第i個字元
- char c; // 讀取到的字元
- int isLastBlank = 0; // 上個字元是否是空格
- int charNum = 0; // 當前行的字元數
- int wordNum = 0; // 當前行的單詞數
- if( (fp=fopen(filename, "rb")) == NULL ){
- perror(filename);
- return NULL;
- }
- printf("line words chars\n");
- // 每次讀取一行資料,儲存到buffer,每行最多隻能有1000個字元
- while(fgets(buffer, 1003, fp) != NULL){
- bufferLen = strlen(buffer);
- // 遍歷緩衝區的內容
- for(i=0; i<bufferLen; i++){
- c = buffer[i];
- if( c==' ' || c=='\t'){ // 遇到空格
- !isLastBlank && wordNum++; // 如果上個字元不是空格,那麼單詞數加1
- isLastBlank = 1;
- }else if(c!='\n'&&c!='\r'){ // 忽略換行符
- charNum++; // 如果既不是換行符也不是空格,字元數加1
- isLastBlank = 0;
- }
- }
- !isLastBlank && wordNum++; // 如果最後一個字元不是空格,那麼單詞數加1
- isLastBlank = 1; // 每次換行重置為1
- // 一行結束,計算總字元數、總單詞數、總行數
- totalNum[0]++; // 總行數
- totalNum[1] += charNum; // 總字元數
- totalNum[2] += wordNum; // 總單詞數
- printf("%-7d%-7d%d\n", totalNum[0], wordNum, charNum);
- // 置零,重新統計下一行
- charNum = 0;
- wordNum = 0;
- }
- return totalNum;
- }
在D盤下建立檔案demo.txt,並輸入如下的內容:
I am Chinese. I love my country. China has 960 square kilometers of territory. China has a population of 1.35 billion. The capital of China is Beijing. By gunge 2014-10-12
執行程式,輸出結果為:
Input file name: d://demo.txt line words chars 1 7 26 2 7 39 3 7 33 4 6 27 5 0 0 6 2 7 7 0 0 8 1 10 Total: 8 lines, 30 words, 142 chars
上面的程式,每次從檔案中讀取一行,放到緩衝區buffer,然後遍歷緩衝區,統計當前行的字元和單詞數。
fgets()函式用於從檔案中讀取一行或指定個數的字元,其原型為:
char * fgets(char *buffer, int size, FILE * stream);
引數說明:
- buffer為緩衝區,用來儲存讀取到的資料。
- size為要讀取的字元的個數。如果該行字元數大於size-1,則讀到 size-1 個字元時結束,並在最後補充' \0';如果該行字元數小於等於 size-1,則讀取所有字元,並在最後補充 '\0'。即,每次最多讀取 size-1 個字元。讀取的字元包括換行符。
- stream為檔案指標。
有的讀者問,為什麼不使用getc(),每次從檔案中讀取一個字元,也無需開闢緩衝區。
這樣沒有問題,但是在處理換行時要注意跨平臺問題,因為不同的平臺對文字檔案換行的處理不一樣,Linux以'\n'為換行符,Windows以'\n\r'為換行符,Mac又以'\r\n'為換行符。所以,使用getc()函式處理換行時比較麻煩。
這裡去繁就簡,通過fgets()讀取整行資料,然後再處理每個字元,直接忽略'\n'和'\r'。
注意:由於每行的結尾會有最多2個位元組長度的換行符,fgets()還會新增NUL,所以緩衝區的長度至少為1003,才能容納每行1000個字元,否則strlen()可能返回垃圾值。
請看程式碼第43行,開啟檔案出錯時,返回NULL,而不是生硬的exit()。這樣可以通知主調函式發生了錯誤,讓主調函式做出適當的處理,或者通知使用者,提高軟體的使用者體驗。
分享個C/C++學習交流QQ群:389318488,群內提供免費教學視訊及資料編譯器,原始碼等等,有大牛解答疑問,能給你提供職業生涯的一些建議!