C程序设计语言 (第二版) 练习 5-15
练习 5-15 增加选项-f,使得排序过程不考虑字母大小写之间的区别。例如,比较a和A时认为它们相等。
注意:代码在win32控制台运行,在不同的IDE环境下,有部分可能需要变更。
IDE工具:Visual Studio 2010
代码块:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAXLINES 5000
#define MAXLEN 1000
#define ALLOCSIZE 10000
static char allocbuf[ALLOCSIZE];
static char *allocp = allocbuf;
char *alloc(int n){
if(allocbuf + ALLOCSIZE - allocp >= n){
allocp += n;
return allocp - n;
}
else{
return 0;
}
}
void afree(char *p){
if(p >= allocbuf && p < allocbuf + ALLOCSIZE){
allocp = p;
}
}
char *lineptr[MAXLINES];
int getline(char *s, int lim){
int c;
char *t = s;
while(--lim > 0 && (c = getchar()) != EOF && c != '\n'){
*s++= c;
}
if(c == '\n'){
*s++ = c;
}
*s = '\0';
return s - t;
}
int readlines(char *lineptr[], int maxlines){
int len, nlines;
char *p, line[MAXLEN];
nlines = 0;
while((len = getline(line, MAXLEN)) > 0){
if(nlines >= maxlines || (p = alloc(len)) == NULL){
return -1;
}
else{
line[len-1] = '\0';
strcpy(p, line);
lineptr[nlines++] = p;
}
}
return nlines;
}
void writelines(char *lineptr[], int nlines){
while(nlines-- > 0){
printf("%s\n", *lineptr++);
}
}
void swap(void *v[], int i, int j){
void *temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
int numcmp(const void *s1, const void *s2){
double v1, v2;
v1 = atof(*(const char **)s1);
v2 = atof(*(const char **)s2);
if(v1 < v2){
return -1;
}
else if(v1 > v2){
return 1;
}
else{
return 0;
}
}
void toLowerCase(char *newstr, char *str) {
int i;
for(i = 0; str[i] != '\0'; i++){
if(isupper(str[i])){
newstr[i] = tolower(str[i]);
}
else{
newstr[i] = str[i];
}
}
newstr[i] = '\0';
}
void qsort(void *v[], int left, int right, int(*comp)(const void*, const void*), int sign){
int i, last;
if(left >= right){
return;
}
swap(v, left, (left + right) / 2);
last = left;
for(i = left + 1; i <= right; i++){
if(sign == 0){
if((*comp)(v[i], v[left]) < 0){
swap(v, ++last, i);
}
}
if(sign == 1){
if((*comp)(v[i], v[left]) > 0){
swap(v, ++last, i);
}
}
if(sign == 2){
char t1[80], t2[80];
toLowerCase(t1, (char*)v[i]);
toLowerCase(t2, (char*)v[left]);
if((*comp)(t1, t2) < 0){
swap(v, ++last, i);
}
}
}
swap(v, left, last);
qsort(v, left, last - 1, comp, sign);
qsort(v, last + 1, right, comp, sign);
}
int main(int argc, char *argv[]){
int nlines;
int numeric = 0;
int sign = 0;
if(argc > 1){
if(strcmp(argv[1], "-n") == 0){
numeric = 1;
sign = 0;
}
if(strcmp(argv[1], "-n") == 0 && strcmp(argv[2], "-r") == 0){
numeric = 1;
sign = 1;
}
if(strcmp(argv[1], "-f") == 0){
numeric = 1;
sign = 2;
}
}
if((nlines = readlines(lineptr, MAXLINES)) >= 0){
qsort((void**)lineptr, 0, nlines - 1, (numeric ? numcmp : (int (*)(const void *,const void *))strcmp), 2);
writelines(lineptr, nlines);
system("pause");
return 0;
}
else{
printf("Error: input too big to sort!\n");
system("pause");
return 1;
}
system("pause");
return 0;
}