Тема: Вправа 5.15 КіР: Ігнорування регістру в порівнянні двох рядків
Вітаю, форумчани!
Виконую я цю вправу і не можу зрозуміти що я роблю не правильно:
Перевіряємо з опцією -f
Зробимо простий ввід:
aaa
aaA
aAA
AAA
Який програма має визначати як тотожні рядки і функція strcmp має повернути 0.
Так і є, але після цього qsort все одно сортує якось рядки і ефект несортування в такому випадку не досягається.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXLINES 5000 /* max #lines to be sorted */
char *lineptr[MAXLINES]; /* pointers to text lines */
int ign_case = 0;
int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines, int reversal);
void qsort1(void *lineptr[], int left, int right, int (*comp)(void *, void *));
int numcmp(char *, char *);
int strcmp1(char *, char *);
/* sort input lines */
int main(int argc, char *argv[])
{
int nlines; /* number of input lines read */
int numeric = 0, reversal = 0;
printf("Soring lines:\n");
if(argc>1){
while(argc-- > 1){
if(strcmp(argv[argc], "-n") == 0){
numeric = 1;
printf(" numeric\n");
} else if(strcmp(argv[argc], "-r") == 0){
reversal = 1;
printf(" reversal\n");
} else if(strcmp(argv[argc], "-f") == 0){
ign_case = 1;
printf(" ignore case\n");
} else
printf("[ERROR] Unknown param: %s\n", argv[argc]);
}
} else {
printf(" alphabetical\n");
}
if((nlines = readlines(lineptr, MAXLINES)) >= 0) {
qsort1((void **) lineptr, 0, nlines-1,
(int (*)(void*, void*))(numeric ? numcmp : strcmp1));
writelines(lineptr, nlines, reversal);
return 0;
} else {
printf("error: input too big to sort\n");
return 1;
}
}
#define MAXLEN 1000 /* max length of any input line */
int getline1(char *, int);
char *alloc(int);
/* readlines: read input lines */
int readlines(char *lineptr[], int maxlines){
int len, nlines;
char *p, line[MAXLEN];
nlines = 0;
while ((len = getline1(line, MAXLEN)) > 0)
if (nlines >= maxlines || (p = alloc(len)) == NULL)
return -1;
else {
line[len-1] = '\0'; /* delete newline */
strcpy(p, line);
lineptr[nlines++] = p;
}
return nlines;
}
int getline1(char *s, int max){
int i=0;
while((*s = getchar()) != '\n' && *s != EOF && i < max-1){
s++;
i++;
}
if(*s == '\n')
i++;
if(*s == EOF)
return 0;
return i;
}
/* writelines: write output lines */
void writelines(char *lineptr[], int nlines, int reversal){
int i;
if(reversal){
while (nlines-- > 0)
printf("%s\n", lineptr[nlines]);
}
while (nlines-- > 0)
printf("%s\n", *lineptr++);
}
/* qsort1: sort v[left]...v[right] into increasing order */
void qsort1(void *v[], int left, int right, int(*comp)(void *, void *)){
int i, last;
void swap(void *v[], int i, int j);
if (left >= right) /* do nothing if array contains */
return; /* fewer than two elements */
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);
qsort1(v, left, last-1, comp);
qsort1(v, last+1, right, comp);
}
/* swap: interchange v[i] and v[j] */
void swap(void *v[], int i, int j){
void *temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
#define ALLOCSIZE 10000 /* size of available space */
static char allocbuf[ALLOCSIZE]; /* storage for alloc */
static char *allocp = allocbuf; /* next free position */
char *alloc(int n) /* return pointer to n characters */
{
if (allocbuf + ALLOCSIZE - allocp >= n) { /* it fits */
allocp += n;
return allocp - n; /* old p */
} else /* not enough room */
return 0;
}
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;
}
int strcmp1(char *s1, char *s2){
/*!!!*/ if(ign_case){
/*!!!*/ while(*s1 == *s2 ||
/*!!!*/ ( (*s1 < *s2) ? (*s1+32 == *s2) : (*s2+32 == *s1) ) ){
/*!!!*/ printf("%c comp %c\n", *s1, *s2);
/*!!!*/ s1++;
/*!!!*/ s2++;
/*!!!*/ if(*s1 == '\0')
/*!!!*/ return 0;
/*!!!*/ }
} else {
for( ; *s1 == *s2; s1++, s2++)
if(*s1 == '\0')
return 0;
}
printf("strcmp: %d\n", *s1 - *s2);
return *s1 - *s2;
}