wc命令的C语言实现

时间:2021-05-10 23:26:08

该程序实现了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;
}


运行结果如下:
 
wc命令的C语言实现

如果对文件进行操作,在参数选项后面加上文件名即可,注意要加绝对路径