wc命令的C語言實現

該程序實現了wc的 -l -m -c -L -w這五個參數的(可組合使用)功能,首先關於其參數man的定義如下:

-c, --bytes  print the byte counts	//字節數	
 -m, --chars print the character counts		//字符數
-l, --lines print the newline counts		//行數
-L, --max-line-length print the length of the longest line	//最大行長度
 -w, --words print the word counts 	//單詞數
源代碼如下:
#include<stdio.h>
#include<unistd.h>
#include<sys/stat.h>
#include<stdlib.h>
struct message{
		int lines;
		int words;
		int max_line_length;
		int size;
		int chars;
}info;
void error_print(char str[]){
		printf("Error:%s",str);
}
void init(char filename[]){
		struct stat get_message = {};
		FILE *fp;
		int ret_stat = stat(filename,&get_message);/*用stat函數讀取filenmae文件的信息,並將結果寫到get_message結構體中*/
		if(ret_stat == -1){//stat函數不出錯則進行信息輸出
				error_print(filename);
				return ;
		}
		mode_t mode = get_message.st_mode;		//接收文件信息,用於下面判斷是不是目錄
		int length = 0;
		if(S_ISDIR(mode))	//如果是目錄,輸出錯誤
				printf("Error %s is dir\n0\t0\t0\t%s",filename,filename);
		else{
				info.size = get_message.st_size;	//文件字節大小 wc -c
				fp = fopen(filename,"r");	//以只讀方式打開指定文件
				char ch;
				int flag = 0;
				while((ch = fgetc(fp))!=EOF){	//一直讀到文件尾
						info.chars++;		//字符數加1 wc -m

						if(ch != '\n'){

								length++;	//記錄當前行的長度 wc -L
						}
						if(ch == '\n'){
								info.lines ++;	//行數加1 wc -l
								if(length>info.max_line_length)
										info.max_line_length = length;	//更新最大長度
								length = 0;
						}
						if(ch == '\t' || ch == ' ' || ch == '\n'){
								flag = 0;		//計算單詞數 wc -w
								continue;
						}
						else{

								if(flag == 0){
										info.words++;	//計算單詞數 wc -w
										flag = 1;
								}
						}
				}
				fclose(fp);
		}

}
//計算鍵盤輸入內容的相關信息,即參數中沒有指定要打開的文件
void EmptyFile(){
		char ch;
		int flag = 0;
		int length = 0;

		while((ch = getchar())!=EOF){
				info.chars++;
				info.size += sizeof(ch);	//字節累加
				if(ch != '\n'){
						length++;
				}
				if(ch == '\n'){
						info.lines ++;
						if(length>info.max_line_length)
								info.max_line_length = length;
						length = 0;
				}
				if(ch == '\t' || ch == ' ' || ch == '\n'){
						flag = 0;
						continue;
				}
				else{

						if(flag == 0){
								info.words++;
								flag = 1;
						}
				}

		}
}
int main(int argc,char *argv[]){

		if(argc == 2){
				if(argv[1][0] != '-'){
						init(argv[1]);
						printf("%d %d %d %s\n",info.lines,info.words,info.size,argv[1]);
						return 0;
				}
				else{	//未指定打開文件,類似 wc -lmwcL
						EmptyFile();

				}
		}
		else if(argc == 1){		//未指定打開文件和要輸出的參數,(默認輸出 -lwc)
				EmptyFile();
				printf("%d\t%d\t%d\n",info.lines,info.words,info.size);
				return 0;
		}
		else if(argc == 3){
				init(argv[2]);
		}
		int num;
		while((num = getopt(argc,argv,"lwmcL"))!=-1){
				switch(num){
						case 'l':
								printf("%d\t",info.lines);
								break;
						case 'w':
								printf("%d\t",info.words);
								break;
						case 'm':
								printf("%d\t",info.chars);
								break;
						case 'c':
								printf("%d\t",info.size);
								break;
						case 'L':
								printf("%d\t",info.max_line_length);
								break;
				}
		}
		if(argc != 2 && argv[1][0] != '-')	//一定要判斷,否則會越界
				printf("%s\n",argv[2]);


		return 0;
}


運行結果如下:


如果對文件進行操作,在參數選項後面加上文件名即可,注意要加絕對路徑

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章