说明:给出git地址是由于码云不支持TOC标签,我直接写锚定代码他也不支持,可是github却能够,因此加上一个github地址linux
git不支持TOC标签生成目录(当场翻白眼)(gitee和github都不支持)git
可是好的是,github仍是能够实现锚定功能的,可是gitee殊不知道为何不行,因此我也给了一个github的地址。github
. ├── bin │ ├── linux_amd64 │ │ ├── input │ │ ├── my.ini │ │ ├── result.log │ │ ├── result.txt │ │ └── wc │ └── windows │ ├── wc32.exe │ └── wc64.exe ├── image │ └── whole_flow_chart.png ├── readme.md └── src ├── function.c ├── wc.c └── wc.h
wc接收一个文本文件,并统计这个文本文件中的信息(行数、字数等)算法
wc.exe -c file.c //返回文件 file.c 的字符数shell
wc.exe -w file.c //返回文件 file.c 的单词总数windows
wc.exe -l file.c //返回文件 file.c 的总行数markdown
wc.exe -o outputFile.txt file.c //将结果输出到指定文件outputFile.txtapp
我在原来的基本上加了一个帮助选项,由于以为这样更适用:
wc.exe -h //显示帮助信息
注意:
参数的形式有两种:长选项、短选项,选项间能够组合,长选项用空格隔开各个参数
例: wc.exe --word --charater file.c
短选项能够多个直接叠加或者,也像长选项同样分开写
例: wc.exe -wc file.c
wc.exe -w -c file.c
对于一个命令行程序,它能够接受来自命令行的参数。
c语言的main函数中有两个参数:int main (int argc, char
,这两个参数就是用于这个参数的输入。
*argv[])
argc 一个整数,表明有多少个命令行参数,在此注意两个点
一、 参数间是用空格格开的;
二、程序名是第一个参数。
argv[i]是一个指针,指向第i个参数的首地址
理解了以上的两个参数就简单了,只须要作一些基本的字符串处理就能够了。
这个参数单独说是由于这个参数不能和别的参数混用,因此我在程序里面是单独写的,一开始就判断是否用户须要的是help帮助,若是是的话,那么彻底没必要要再运行程序(打开文件),直接exit停止进程
。
这三个参数都是一个路数:
一、打开文件;
二、判断要作的操做;
三、执行操做。
它们间只有步骤3是不一样的,因此有理由把3写成不一样的函数,再由2判断执行哪一个。
有一些细节问题是能够考虑的。
好比,由于单复数的关系,有一行/个 单词/字母,应该是不一样的表达(是否有s)
额外就是判断一个单词的算法也是值得考虑的问题,个人想法是,若是一个字符,它本身是一个字母,它前面是一个非字母,那么这就是一个单词的标致。
这个参数比较特殊,由于它后面跟了一个文件,要作的事情是把输出的内容存到的文件换成用户自定义的名字。
总的来讲是两件事情
void lines_searching(FILE *fp, bool out_to_files){ int line = 0; int ch = 0; while(!feof(fp)){ ch = fgetc(fp); //putchar(ch); if(ch == '\n') line++; else continue; }//of while loop //printf("line is %d\n",line); output_to_sdo(line, "line", out_to_files); }//of character_searching function
void words_searching(FILE *fp, bool out_to_files){ int letter =0; int word = 0; bool is_word = FALSE; while(!feof(fp)){ letter = fgetc(fp); if((letter >= 'a' && letter <= 'z') || (letter >= 'A' && letter <= 'Z' ) || (letter == '\'')){ if(!is_word) //if if_word is false, it means this is a brand new word is_word = TRUE; }//of if else{ if(is_word){ word ++; is_word = FALSE; }//of if else continue; }//of else }//of while loop output_to_sdo(word, "word", out_to_files); }//of words_searching function
这个里面有一些问题要考虑:
letter != '\n' || letter != '\t' || letter != ' '
void output_to_sdo(int number, char* name, bool out_to_files){ char result_fp_name[50];//the name of the result files char result[50]; //printf("%s\n",specific_file); if(number == 0) sprintf(result, "No %s in the file\n", name); else if(number == 1) sprintf(result, "1 %s in the file\n", name); else sprintf(result, "%d %ss in the file\n",number,name); printf("%s", result); if(out_to_files){ strcpy(result_fp_name, specific_file); }//of if else{ strcpy(result_fp_name, "result.txt"); }//of else FILE *result_fp = fopen(result_fp_name,"w"); fputs(result, result_fp); fclose(result_fp); }//of function output_to_fdo
主要是作简单的系统测试,等价类和边界值
从输入的数据入用进行分析,本程序的输入信息就是从命令行接受的一些数据,这些个数据能够分为两人类
选项:控制程序运行的方式和输出的方式,这类选项能够分为三类
1.1 -h
:这个选项不能和别人一用,并且这个选项不带参数,它也不容许程序再带参数;
1.1 -o
:这个选项须要和别人组合在一块儿用,并且不能单用,在这个选项后面须要带一个参数,并且也须要程序带一个参数;
1.2
-w/-c/-l:它们都是是执行特色的查找任务的,这几个选项不带参数,可是须要程序带一个参数。
参数:在本程序中也就是须要查找的文件,分红这文件存在、不存在。
输入条件 | 有效等价类 | 无效等价类 |
---|---|---|
选项 | -h (1)/ -w(2) / -l(3) / -c(4) / -o out(5) / -w -c(6) | -a(7) / -p(8) / -h -w(9) |
参数 | 文件(10) | 没有文件(11) |
I loved you. But you didn't love me. I felt sad. But you seemed to feel happy. So I begun to hate you.
seven@mylab:~/wordcount/bin/linux_amd64$ cat result.in Usage: wc.exe [OPTIONS]... [FILE] --character -c calculate the numbers of characters in the file --word -w calculate the numbers of words in the file --line -l calculate the numbers of lines in the file --outtofile=x -o x transfer the result to the specific file
seven@mylab:~/wordcount/bin/linux_amd64$ ./wc -h input Wrong Parameter!
seven@mylab:~/wordcount/bin/linux_amd64$ ./wc -w input 23 words in the file seven@mylab:~/wordcount/bin/linux_amd64$ wc -w input 23 input
与linux下自带的wordcount(wc)的结果对比了下
seven@mylab:~/wordcount/bin/linux_amd64$ ./wc -w nothing Fail to Open the File! seven@mylab:~/wordcount/bin/linux_amd64$ wc -w nothing wc: nothing: No such file or directory
seven@mylab:~/wordcount/bin/linux_amd64$ ./wc -l input 5 lines in the file seven@mylab:~/wordcount/bin/linux_amd64$ wc -l input 5 input
seven@mylab:~/wordcount/bin/linux_amd64$ ./wc -l nothing Fail to Open the File! seven@mylab:~/wordcount/bin/linux_amd64$ wc -l nothing wc: nothing: No such file or directory
seven@mylab:~/wordcount/bin/linux_amd64$ ./wc -c input 104 characters in the file seven@mylab:~/wordcount/bin/linux_amd64$ wc -c input 103 input
出现了不一样
seven@mylab:~/wordcount/bin/linux_amd64$ ./wc -c nothing Fail to Open the File! seven@mylab:~/wordcount/bin/linux_amd64$ wc -c nothing wc: nothing: No such file or directory
seven@mylab:~/wordcount/bin/linux_amd64$ ./wc -w -o result.log input 23 words in the file seven@mylab:~/wordcount/bin/linux_amd64$ cat result.log 23 words in the file seven@mylab:~/wordcount/bin/linux_amd64$ wc -w input > result.log seven@mylab:~/wordcount/bin/linux_amd64$ cat result.log 23 input
seven@mylab:~/wordcount/bin/linux_amd64$ ./wc -w -h Fail to Open the File! seven@mylab:~/wordcount/bin/linux_amd64$ ./wc -w -h nohting Fail to Open the File! seven@mylab:~/wordcount/bin/linux_amd64$ ./wc -w -h input Wrong Parameter! 23 words in the file
这个用例没有经过
for(int i = 1; i < argc-1; i++){ if(argv[i][0] == '-'){ switch(argv[i][1]){ case 'c': print_characters = TRUE; break; case 'l': print_lines = TRUE; break; case 'w': print_words = TRUE; break; case 'o': out_to_files = TRUE; strcpy(specific_file,argv[i+1]); //printf("%s\n",specific_file); break; case 'h'://add a case to detect -h printf("-h parameter should work alone!\n"); exit(0); default: printf("Wrong Parameter!\n"); }//of switch }//of if }//of for loop
seven@mylab:~/wordcount/src$ ./a.out -h input -h parameter should work alone!
经过测试!
检查用例7
seven@mylab:~/wordcount/bin/linux_amd64$ printf "I hate you\nYou hate me\n" I hate you You hate me seven@mylab:~/wordcount/bin/linux_amd64$ printf "I hate you\nYou hate me\n" > my.ini seven@mylab:~/wordcount/bin/linux_amd64$ ./wc -c my.ini 24 characters in the file seven@mylab:~/wordcount/bin/linux_amd64$ wc -c my.ini 23 my.ini
seven@mylab:~/wordcount/bin/linux_amd64$ echo "I really made a mistake??" > my.ini seven@mylab:~/wordcount/bin/linux_amd64$ ./wc -c my.ini 27 characters in the file seven@mylab:~/wordcount/bin/linux_amd64$ wc -c my.ini 26 my.ini
while(!feof(fp)){ fgetc(fp); character ++; }//of while loop
这样把最后一个结尾字符也记上了,因此应该把结果减去1.
seven@mylab:~/wordcount/bin/linux_amd64$ ./wc -w my.ini 5 words in the file seven@mylab:~/wordcount/bin/linux_amd64$ wc -w my.ini 5 my.ini seven@mylab:~/wordcount/bin/linux_amd64$ ./wc -w input 23 words in the file seven@mylab:~/wordcount/bin/linux_amd64$ wc -w input 23 input
seven@mylab:~/wordcount/src$ ./a.out -c input input, character number:23
#!/bin/sh #Author: seven #date: 2018/09/27 #aim: an automatic script to test the program #a function to print test result #function will receive 2 parameters, #first is the type of the test, #second is whether the test tested as expected test_result_print(){ if [ $2 -eq 1 ] then echo `date "+%Y-%m-%d %H:%M:%S"` " $1 test succeeded!" | tee -a test_log.txt else echo `date "+%Y-%m-%d %H:%M:%S"` " $1 test met with failure!" | tee -a test_log.txt fi } compare_result_with_standard(){ if [ "$1" = "$2" ] then if_test_success=1 else if_test_success=0 fi } test_file_name="input" #Here is the test for ./wc -h #the ideal result is the usage of the program standard_result="Usage: wc.exe [OPTIONS]... [FILE] --character -c calculate the numbers of characters in the file --word -w calculate the numbers of words in the file --line -l calculate the numbers of lines in the file --outtofile=x -o x transfer the result to the specific file" result=`./wc -h` compare_result_with_standard "$result" "$standard_result" test_result_print "wc -h" $if_test_success #Here is the test for ./wc -h input #the ideal result is to print "-h parameter should work alone!" standard_result="-h parameter should work alone!" result=`./wc -h input` compare_result_with_standard "$result" "$standard_result" test_result_print "wc -h print" $if_test_success #Here is the test for wc -w input standard_result=`wc -w $test_file_name | sed 's/[^0-9]//g'` result=`./wc -w $test_file_name | sed 's/[^0-9]//g'` compare_result_with_standard "$result" "$standard_result" test_result_print "wc -w input" $if_test_success #Here is the test for wc -w nothing standard_result="Fail to Open the File!" result=`./wc -w nothing` compare_result_with_standard "$result" "$standard_result" test_result_print "wc -w nothing" $if_test_success #Here is the test for wc -l nothing standard_result="Fail to Open the File!" result=`./wc -l nothing` compare_result_with_standard "$result" "$standard_result" test_result_print "wc -l nothing" $if_test_success #Here is the test for wc -c input standard_result=`wc -c $test_file_name | sed 's/[^0-9]//g'` result=`./wc -c $test_file_name | sed 's/[^0-9]//g'` compare_result_with_standard "$result" "$standard_result" test_result_print "wc -c input" $if_test_success #Here is the test for wc -c nothing standard_result="Fail to Open the File!" result=`./wc -c nothing` compare_result_with_standard "$result" "$standard_result" test_result_print "wc -c nothing" $if_test_success #Here is the test for wc -w -o result.log input standard_result=`wc -w $test_file_name | sed 's/[^0-9]//g'` result=`./wc -w -o result.log $test_file_name | sed 's/[^0-9]//g'` compare_result_with_standard "$result" "$standard_result" test_result_print "wc -w -o result.log input in std output" $if_test_success result=`cat result.log | sed 's/[^0-9]//g'` compare_result_with_standard "$result" "$standard_result" test_result_print "wc -w -o result.log input in outputfile" $if_test_success
测试结果:
seven@mylab:~/wordcount/bin/linux_amd64$ ./test.sh 2018-09-27 16:11:58 wc -h test succeeded! 2018-09-27 16:11:58 wc -h print test succeeded! 2018-09-27 16:11:58 wc -w input test succeeded! 2018-09-27 16:11:58 wc -w nothing test succeeded! 2018-09-27 16:11:58 wc -l nothing test succeeded! 2018-09-27 16:11:58 wc -c input test succeeded! 2018-09-27 16:11:58 wc -c nothing test succeeded! 2018-09-27 16:11:58 wc -w -o result.log input in std output test succeeded! 2018-09-27 16:11:58 wc -w -o result.log input in outputfile test succeeded!
完成一个还算比较难的程序(由于我总想着GNU写过了的wc)对一个学生而言并不是易事,参考了不少(其实也很少),见下: