이 프로그램은 main에 전달 된 인수에 따라 알파벳 순/숫자로 정렬합니다.c 함수 포인터
그리고이 핸드북에서 k & R : 대문자와 소문자를 함께 접어서 정렬 할 때 대소 문자 구분을하지 않도록 옵션을 추가하십시오. 예를 들어, a와 A는 같음을 비교합니다.
my_strcmp에 쓴 내용이 좋나요? 그리고 -r과 -n과 함께 잘 작동할까요? (r- 역순, n- 숫자 정렬).
나는이 아이디어가 klc 위키에서 해결책을 제시하지 않았기 때문에 여기에 여러분의 의견을 묻습니다.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAXBUF 10000
#define MAXLINES 5000
char *lineptr[MAXLINES];
int readlines(char *lineptr[], char buffer[], int nlines);
void writelines(char *lineptr[], int nlines);
void qsort(void **lineptr, int left, int right, int (*comp)(void *, void *));
int numcmp(char *, char *);
int reverse = 0;
int numeric = 0;
int fold = 0;
int my_strcmp(char *s1, char *s2)
{
char *p1 = (reverse) ? s2 : s1;
char *p2 = (reverse) ? s1 : s2;
if(fold) {
while(toupper(*p1) == toupper(*p2)) {
p1++, p2++;
if(!*p1)
return 0;
}
return toupper(*p1) - toupper(*p2);
}
return strcmp(p1, p2);
}
int main(int argc, char *argv[])
{
int nlines;
char buffer[MAXBUF];
int i = 1;
for(i = 1; i < argc; i++) {
if(strcmp(argv[i], "-n") == 0) {
numeric = 1;
} else if(strcmp(argv[i], "-r") == 0) {
reverse = 1;
} else if(strcmp(argv[i], "-f") == 0) {
fold = 1;
} else {
printf("illegal argument\n");
}
}
if((nlines = readlines(lineptr, buffer, MAXLINES)) >= 0) {
qsort((void **)lineptr, 0, nlines - 1,
(numeric ? (int (*)(void *, void *))numcmp : (int (*)(void *, void *))my_strcmp));
writelines(lineptr, nlines);
getchar();
return 0;
} else {
printf("input too big to sort\n");
return 1;
}
}
void writelines(char *lineptr[], int nlines)
{
int i;
for (i = 0; i < nlines; i++)
printf("%s\n", lineptr[i]);
}
int getline(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;
++i;
}
s[i] = '\0';
return i;
}
#define MAXLEN 1000
int readlines(char *lineptr[], char *buffer, int maxlines)
{
int len, nlines;
char *p, line[MAXLEN];
nlines = 0;
p = buffer;
while ((len = getline(line, MAXLEN)) > 0)
if (p - buffer + len > MAXBUF)
return -1;
else {
line[len-1] = '\0'; /* delete newline */
strcpy(p, line);
lineptr[nlines++] = p;
p += len;
}
return nlines;
}
void qsort(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);
qsort(v, left, last - 1, comp);
qsort(v, last + 1, right, comp);
}
#include <stdlib.h>
int numcmp(char *p1, char *p2)
{
char *s1 = reverse ? p2 : p1;
char *s2 = reverse ? p1 : p2;
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;
}
하나 더 질문드립니다. 나는 옵션 -d (디렉토리 순서)를 추가하려고 시도했다. "글자 수와 공백에 대해서만 비교를한다. -f와 함께 작동하는지 확인한다." 그리고 my_strcmp를 편집하는 방법에 대해 약간 당황 스럽다. 이것은 내가 한 일입니다.
그러나 좋은지 잘 모르겠지만.
또한 디렉토리와 폴드가 0 인 경우 대소 문자를 처리하는 my_strcmp2를 작성했습니다. 그것은 나에게 확인을 보이는 첫눈에 ...
int my_strcmp2(char *s1, char *s2)
{
char *p1 = (reverse) ? s2 : s1;
char *p2 = (reverse) ? s1 : s2;
while(*p1 == *p1 && *p1) {
p1++;
p2++;
if(directory) {
while(!isdigit(*p1) && !isspace(*p1) && !isalpha(*p1) && *p1)
p1++;
while(!isdigit(*p2) && !isspace(*p2) && !isalpha(*p2) && *p2)
p2++;
}
}
return *p1 - *p2;
}
다른 플래그를 결합 할 수있는 경우에는 실제로 작동하지 않습니다 (또는 모든 가능한 조합에 대해 함수를 작성해야 함). – interjay
@interjay : 많은 수의 플래그를 다른 방법으로 결합 할 수 있다면 다루기 힘들어집니다. 다른 한편으로는, 적어도 지금까지 물어 보았던 것을 위해, 나는 그것이 가장 깨끗한 접근법이라고 생각한다. 임의로 조합 할 수있는 많은 플래그가 궁극적으로 어떤 경우에도 많은 코드 경로로 이어질 것이므로 대부분 패키지를 어떻게 포장하는지에 대한 질문입니다. 서로 다른 경로가 많은 코드를 공유 할 수 있다면이를 단일 함수로 결합하는 것이 좋습니다. 예를 들어 대소 문자를 구분하거나 대소 문자를 구분하는 비교는 거의 아무 것도 공유하지 않습니다. –