> 文档中心 > 100 Days of Code-day35-目录排序小助手

100 Days of Code-day35-目录排序小助手


添加 -d (代表目录顺序) 选项,该选项仅对字母、数字和空格进行比较。确保它与 -f 一起工作。

本程序设计的思路是将mystrcmp函数的功能并入到插入charcmp函数中,与此同时根据题目扩充了charcmp函数的内容。

if (argc)printf("Usage: sort -fnr\n");elseif ((nlines = readline(lineptr, MaxLines)) >= 0)//这里并不意味着nlines=0的时候需要参与排序,而是说这里为了方便操作//将无输入内容一并归入有输入内容中,也就是将其当做一种正常情况。否则要多设置一个返回标志。{if (option & Numeric)myqsort((void **)lineptr, 0, nlines - 1, (int(*)(void*, void*))numcmp);elsemyqsort((void **)lineptr, 0, nlines - 1, (int(*)(void*, void*))charcmp);writeline(lineptr, nlines, option & Decr);}else {printf("input too big to sort\n");rc = -1;}return rc;

从如上程序中我们可以看出:
其中的这一部分向我们展示了程序将f,r这两种命令都归入到charcmp函数中了。

if (option & Numeric)myqsort((void **)lineptr, 0, nlines - 1, (int(*)(void*, void*))numcmp);elsemyqsort((void **)lineptr, 0, nlines - 1, (int(*)(void*, void*))charcmp);

那么深入到charcmp函数中,我们又会发现什么呢?

//将原先实现mystrcmp的功能的程序也归入到charcmp中/* charcmp: return <0 if s 0 if s > t */int charcmp(char *s, char *t){char a, b;int fold = (option & Capital) ? 1 : 0;int dir = (option & DIR) ? 1 : 0;do{if (dir){while (!isalnum(*s) && *s != ' ' && *s != '\0')s++;//isalnum的作用是检查某个字符是否为一个字母(a-z,A-Z),或者数字(0-9)//所以说如果不是则忽略该字符while (!isalnum(*t) && *t != ' ' && *t != '\0')t++;}a = fold ? tolower(*s) : *s;s++;b = fold ? tolower(*t) : *t;t++;if (a == b && a == '\0')//如果没有a=='\0',一遇到两个字符串的某个字符相等的情况就会停止循环return 0;//当两个字符串进行比较时,什么情况下两者才会相等?只有当两者参与比较的字符相同,同时还要两个字符串的长度相等。//那么如何直观地表现出两个字符串的长度相同呢?仔细一想,当两者长度相同的前提下,在该程序中,//字符串s是先到达终止符的,那么相对应的参与比较的字符a为终止符时,比较结束} while (a == b);return a - b;}

我们发现了其精髓之所在:

如果输入了指令d,表明要进行目录排序

if (dir){while (!isalnum(*s) && *s != ' ' && *s != '\0')s++;while (!isalnum(*t) && *t != ' ' && *t != '\0')t++;}

isalnum函数的作用是检查某个字符是否为一个字母(a-z,A-Z),或者数字(0-9)
那么当不是字母、数字、空格、终止符时,就直接将该字符忽略掉,不让其参与比较
接下来就是对于是否应该忽略大小写的判断

a = fold ? tolower(*s) : *s;s++;b = fold ? tolower(*t) : *t;t++;

通过条件表达式,当fold为1时,那就需要先将字符转化为其小写字符,然后再将其与其他字符进行比较。