非常不清楚是要对每行中的所有字符进行排序,还是要对数组中的字符串数组进行排序(或两者都排序)。两者都可以实现,但两者对compare 的要求略有不同。
假设您想要对数组的数组进行排序(如果将它们设为字符串会更容易),您会期望输出如下:
$ ./bin/sortcapsfirst
azghtdffopAsAfp
poiuyjklhgADHTp
hgjkFfGgBnVUuKk
lokijuhygtfrdek
AaaAdDcCFfgGhHI
AaaAdDcCFfgGhHI
azghtdffopAsAfp
hgjkFfGgBnVUuKk
lokijuhygtfrdek
poiuyjklhgADHTp
否则,您需要先对每一行进行排序(先对每个大写字母排序,再对相同的小写字母排序),然后再对数组进行排序。这将导致输出如下:
$ ./bin/sortcapsfirst
azghtdffopAsAfp
poiuyjklhgADHTp
hgjkFfGgBnVUuKk
lokijuhygtfrdek
AaaAdDcCFfgGhHI
AAaaCcDdFfGgHhI
AAadfffghoppstz
ADgHhijkloppTuy
BFfGgghjKkknUuV
defghijkklortuy
你可能会让自己变得比需要的更难。通常,默认情况下,LOCALE 的自然字符串排序将首先对 Caps 进行排序。在对数组s1 排序的情况下,对行进行排序以便大写在小写之前排序,您只需将列数设置为16(为 nul-terminating 字符提供空间) 然后在您的compare 例程中调用strcmp,例如:
int compare(const void *w1, const void *w2) {
const char *a1 = w1;
const char *a2 = w2;
return strcmp (a1, a2);
}
将它们放在一个示例中,并在遇到 nul-terminating 字符时正确终止每个 j 循环,您可以这样做:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define N 5
#define R 16
int compare(const void *w1, const void *w2);
int main(void) {
char s1[][R] = {{ "azghtdffopAsAfp" },
{ "poiuyjklhgADHTp" },
{ "hgjkFfGgBnVUuKk" },
{ "lokijuhygtfrdek" },
{ "AaaAdDcCFfgGhHI" }};
int i, j;
for (i = 0; i<N; i++) {
for (j = 0; s1[i][j] && j<R; j++) {
putchar(s1[i][j]); /* don't use printf to print a single-char */
}
putchar('\n');
}
qsort (s1, N, sizeof *s1, compare); /* sort array (rows) */
putchar('\n');
for (i = 0; i<N; i++) {
for (j = 0; s1[i][j] && j<R; j++) {
putchar(s1[i][j]);
}
putchar('\n');
}
return 0;
}
int compare(const void *w1, const void *w2) {
const char *a1 = w1;
const char *a2 = w2;
return strcmp (a1, a2);
}
对于第二种情况,您将每行中的大写字母排在等效的小写字母之前,然后对数组进行排序,您只需添加第二个 qsort 比较函数并按原样调用它,然后再调用 @987654333 @ 在整个数组上。例如(将每个大写字母排在对应的小写字母之前):
int compare (const void *w1, const void *w2) {
const char *a1 = w1;
const char *a2 = w2;
while (*a1 && *a2)
{
int r = tolower(*a1) - tolower(*a2);
if (!r) {
if (*a1 - *a2)
return *a1 - *a2 > 0 ? 1 : -1;
}
else
break;
++a1;
++a2;
}
// return *a1 - *a2; /* to sort ALLcapsfirst */
return tolower(*a1) - tolower(*a2);
}
然后像第一个示例中那样调用qsort 对数组中的行进行排序:
int comparestr (const void *w1, const void *w2) {
const char *a1 = w1;
const char *a2 = w2;
return strcmp (a1, a2);
}
将它们放在同一个示例中(使用 nul-terminated 行),您可以这样做:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define N 5
#define R 16
int compare (const void *w1, const void *w2);
int comparestr (const void *w1, const void *w2);
int main (void) {
char s1[][R] = {{"azghtdffopAsAfp"},
{"poiuyjklhgADHTp"},
{"hgjkFfGgBnVUuKk"},
{"lokijuhygtfrdek"},
{"AaaAdDcCFfgGhHI"}};
int i, j;
for (i = 0; i < N; i++) {
for (j = 0; s1[i][j] && j < R; j++)
putchar(s1[i][j]);
putchar('\n');
}
for (i = 0; i < N; i++) /* sort arrays */
qsort (s1[i], R - 1, sizeof *(s1[i]), compare);
qsort (s1, N, sizeof *s1, comparestr); /* sort array */
putchar('\n');
for (i = 0; i < N; i++) {
for (j = 0; s1[i][j] && j < R; j++)
putchar(s1[i][j]);
putchar('\n');
}
return 0;
}
int compare (const void *w1, const void *w2)
{
const char *a1 = w1;
const char *a2 = w2;
while (*a1 && *a2) {
int r = tolower (*a1) - tolower (*a2);
if (!r) {
if (*a1 - *a2)
return *a1 - *a2 > 0 ? 1 : -1;
} else
break;
++a1;
++a2;
}
// return *a1 - *a2; /* to sort ALLcapsfirst */
return tolower (*a1) - tolower (*a2);
}
int comparestr (const void *w1, const void *w2)
{
const char *a1 = w1;
const char *a2 = w2;
return strcmp (a1, a2);
}
最后,如上所述,如果您想对 ALLCapsfirst 进行排序,则只需返回 *a1 - *a2 之间的差而不是 tolower (*a1) - tolower (*a2)。例如使用return *a1 - *a2; 排序将是:
AACDFGHIaacdfgh
AAadfffghoppstz
ADHTghijkloppuy
BFGKUVfgghjkknu
defghijkklortuy
把事情看一遍。我可能完全误解了你的目标。如果是这样,请留言,我可以进一步提供帮助。