添加 -d (代表目录顺序) 选项,该选项仅对字母、数字和空格进行比较。确保它与 -f 一起工作。
本程序设计的思路是将mystrcmp函数的功能并入到插入charcmp函数中,与此同时根据题目扩充了charcmp函数的内容。
if (argc)
printf("Usage: sort -fnr\n");
else
if ((nlines = readline(lineptr, MaxLines)) >= 0) //这里并不意味着nlines=0的时候需要参与排序,而是说这里为了方便操作
//将无输入内容一并归入有输入内容中,也就是将其当做一种正常情况。否则要多设置一个返回标志。
{
if (option & Numeric)
myqsort((void **)lineptr, 0, nlines - 1, (int(*)(void*, void*))numcmp);
else
myqsort((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);
else
myqsort((void **)lineptr, 0, nlines - 1, (int(*)(void*, void*))charcmp);
那么深入到charcmp函数中,我们又会发现什么呢?
//将原先实现mystrcmp的功能的程序也归入到charcmp中
/* charcmp: return <0 if s < t, 0 if s ==t, >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时,那就需要先将字符转化为其小写字符,然后再将其与其他字符进行比较。