該程序根據傳遞給main的參數按字母順序/數字排序行。c函數指針
正在從事這個練習k & R現在: 添加選項-f將大寫和小寫疊加在一起,以便在排序過程中不區分大小寫;例如,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有點困惑。這是我做過什麼:
int my_strcmp(char *s1, char *s2)
{
char *p1 = (reverse) ? s2 : s1;
char *p2 = (reverse) ? s1 : s2;
if(directory) {
while(!isdigit(*p1) && !isspace(*p1) && !isalpha(*p1) && *p1)
p1++;
while(!isdigit(*p2) && !isspace(*p2) && !isalpha(*p2) && *p2)
p2++;
}
if(fold) {
while(toupper(*p1) == toupper(*p2)) {
p1++, p2++;
if(!*p1)
return 0;
if(directory) {
while(!isdigit(*p1) && !isspace(*p1) && !isalpha(*p1))
p1++;
while(!isdigit(*p2) && !isspace(*p2) && !isalpha(*p2))
p2++;
}
}
return toupper(*p1) - toupper(*p2);
}
return my_strcmp2(p1, p2);
}
但是我不敢肯定,如果它的好。
我也寫了my_strcmp2,它處理的情況下,如果目錄和fold是零。
然後我們只是strcmp的他們,但我們必須跟蹤如果目錄1名藏漢...
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 2010-01-12 19:04:41
@interjay:的確,如果你可以用不同的方式組合大量的標誌,這將變得笨拙。另一方面,至少對於迄今爲止提出的問題,我認爲這是最乾淨的方法。我還會注意到很多可以任意組合的標誌在任何情況下最終都會導致大量的代碼路徑,所以這主要是您如何打包這些代碼的問題。如果不同的路徑可以共享大量的代碼,將它們組合成單個函數可能是值得的 - 但是(例如)區分大小寫和區分大小寫的比較幾乎不分享。 – 2010-01-12 19:16:48