C //练习 5-16 增加选项-d(代表目录顺序)。该选项表明,只对字母、数字和空格进行比较。要保证该选项可以和-f组合在一起使用。

发布时间:2024年01月15日

C程序设计语言 (第二版) 练习 5-16

练习 5-16 增加选项-d(代表目录顺序)。该选项表明,只对字母、数字和空格进行比较。要保证该选项可以和-f组合在一起使用。

注意:代码在win32控制台运行,在不同的IDE环境下,有部分可能需要变更。
IDE工具:Visual Studio 2010

?

代码块:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#define MAXLINES 5000

char *lineptr[MAXLINES];

int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines, int reverse);
void q_sort(void *lineptr[], int left, int right, int (*comp)(void *, void *));
int numcmp(char *, char *);
int strfcmp(char *, char*);
int strdcmp(char *, char *);
int strdfcmp(char *, char *);


int main(int argc, char *argv[]) {
    int nlines;
    int numeric = 0;
    int reverse = 0;
    int fold = 0;
    int dir = 0;

    while (--argc > 0 && (*++argv)[0] == '-') {
        int c;
        while (c = *++argv[0])
            switch (c) {
                case 'n':
                    numeric = 1;
                    break;
                case 'r':
                    reverse = 1;
                    break;
                case 'f':
                    fold = 1;
                    break;
                case 'd':
                    dir = 1;
                    break;
                default:
                    printf("Illegal option: %c\n", c);
                    break;
            }
    }

    if (argc != 0)
        printf("Usage: sort -n -r -f\n");

    printf(numeric ? "Numerical sort\n" : "Lexicographic sort\n");
    printf(reverse ? "Reverse sort\n" : "Normal sort\n");
    printf(fold ? "Case insensitive\n" : "Case sensitive\n");
    printf(dir ? "Directory order\n" : "");

    if ((nlines = readlines(lineptr, MAXLINES)) > 0) {
        if (numeric)
            q_sort((void **) lineptr, 0, nlines - 1,
                    (int (*)(void *, void *)) numcmp);
        else if (dir)
            if (fold)  
                q_sort((void **) lineptr, 0, nlines - 1,
                        (int (*)(void *, void *)) strdfcmp);
            else
                q_sort((void **) lineptr, 0, nlines - 1,
                        (int (*)(void *, void *)) strdcmp);
        else
            if (fold)
                q_sort((void **) lineptr, 0, nlines - 1,
                        (int (*)(void *, void *)) strfcmp);
            else
                q_sort((void **) lineptr, 0, nlines - 1,
                        (int (*)(void *, void *)) strcmp);
        writelines(lineptr, nlines, reverse);
        return 0;
    } else {
        printf("input too big to sort\n");
        return 1;
    }

	system("pause");
	return 0;
}

void q_sort(void *v[], int left, int right, int (*comp)(void *, void *)) {
    int i, last;
    void swap(void *v[], int, int);

    if (left >= right)
        return;
    swap(v, left, (left + right) / 2);
    last = left;
    for (i = left + 1; i <= right; i++)
        if ((*comp)(v[i], v[left]) < 0) 
            swap(v, ++last, i);
    swap(v, left, last);
    q_sort(v, left, last - 1, comp);
    q_sort(v, last + 1, right, comp);
}

int strdcmp(char *s1, char *s2) {
    char a, b;

    do {
        while (!isalnum(*s1) && *s1 != ' ' && *s1 != '\0')
            s1++;
        while (!isalnum(*s2) && *s2 != ' ' && *s2 != '\0')
            s2++;

        a = *s1;
        s1++;
        b = *s2;
        s2++;

        if (a == b && a == '\0')
            return 0;

    } while (a == b);

    return a - b;

}

int strdfcmp(char *s1, char *s2) {
    char a, b;

    do {
        while (!isalnum(*s1) && *s1 != ' ' && *s1 != '\0')
            s1++;
        while (!isalnum(*s2) && *s2 != ' ' && *s2 != '\0')
            s2++;

        a = tolower(*s1);
        s1++;
        b = tolower(*s2);
        s2++;

        if (a == b && a == '\0')
            return 0;

    } while (a == b);

    return a - b;
}

int strfcmp(char *s1, char *s2) {
    for ( ; tolower(*s1) == tolower(*s2); s1++, s2++)
        if (*s1 == '\0')
            return 0;
    return tolower(*s1)-tolower(*s2);
}

int numcmp(char *s1, char *s2) {
    double v1, v2;

    v1 = atof(s1);
    v2 = atof(s2);

    if (v1 < v2)
        return -1;
    else if (v1 > v2)
        return 1;
    else
        return 0;
}

void swap(void *v[], int i, int j) {
    void *temp;

    temp = v[i];
    v[i] = v[j];
    v[j] = temp;
}

#define MAXLEN 1000

int get_line(char line[], int maxline);
char *alloc(int);

int readlines(char *lineptr[], int maxlines) {

    int len, nlines;
    char *p, line[MAXLEN];

    nlines = 0;
    while ((len = get_line(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, int reverse) {

    int i;

    if (reverse)
        for (i = nlines-1; i >= 0; i--)
            printf("%s\n", lineptr[i]);
    else
        for (i = 0; i < nlines; i++)
            printf("%s\n", lineptr[i]);
}

int get_line(char s[], int lim) {
    int c, i;

    for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
        s[i] = c;
    if (c == '\n') s[i++] = c;
    s[i] = '\0';
    return i;
}

#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;
}
文章来源:https://blog.csdn.net/navicheung/article/details/135581228
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。