我一直在寻找解决方案,但似乎找不到与我类似的解决方案。我试图排序 某列的2D char *数组。
char *objs[50][3];
/***** within a loop to populate with values *****/
objs[count][0]=obj->level; //this is a number to be sorted
objs[count][1]=obj->cost; //this is a number
objs[count][2]=obj->short_desc->str; //this is a string
count++;
/***** end loop *********/
qsort(objs, count, sizeof(char *), compare_function); //to sort by obj->level, int values
我删除了我以前的解决方案,因为它显示了各种类型 奇怪的数字甚至不排序。我不是很有经验 C,非常感谢有关如何做到这一点的帮助。
提前谢谢。
答案 0 :(得分:0)
在" C"中排序隐式结构时由2d arrays定义,其中每一行对应一个对象,我发现使用qsort_s()
很有用,因为它允许我传递有关要排序到比较函数中的数组条目的更多信息。
因此,以下内容接受带有nRows
行和nColumns
列的字符串的二维数组,并对sortColumnIndex
指定的列进行排序。提供给context
的额外qsort_s()
指针将排序索引传递给排序方法,而不需要全局变量:
struct sort_on_index_context
{
size_t nRows;
size_t nColumns;
size_t sortColumnIndex;
};
static int compare(void *p_vcontext, const void *ventry1, const void *ventry2)
{
struct sort_on_index_context *p_context = (struct sort_on_index_context *)p_vcontext;
char **entry1 = (char **)ventry1;
char *s1 = entry1[p_context->sortColumnIndex];
char **entry2 = (char **)ventry2;
char *s2 = entry2[p_context->sortColumnIndex];
return strcmp(s1, s2);
}
void sort_on_index(char **objs, size_t nRows, size_t nColumns, size_t sortColumnIndex)
{
struct sort_on_index_context context;
if (sortColumnIndex < 0 || sortColumnIndex >= nColumns)
return; /* Print an error or throw an exception! */
context.nColumns = nColumns;
context.sortColumnIndex = sortColumnIndex;
context.nRows = nRows;
qsort_s(objs, nRows, sizeof(char *) * nColumns, compare, (void *)&context);
}
我们传递sizeof(char *) * nColumns
因为我们希望qsort_s
将每个连续的nColumns
个char指针组视为要按顺序重新排列的单个块。
然后你会称之为:
char *objs[50][3];
size_t nRows = sizeof(objs)/sizeof(objs[0]);
size_t nColumns = sizeof(objs[0])/sizeof(objs[0][0]);
size_t column_id_to_sort = 1; /* or whatever you want to define as your sort key. */
/* Fill up your "objs" array however you like */
/* Now do the sort: */
sort_on_index(&objs[0][0], nRows, nColumns, column_id_to_sort);
修改强>
如果您的开发环境中没有qsort_s
或某些等效项,您可能需要通过静态变量向排序函数传达必要的信息,例如
static struct sort_on_index_context context;
static int compare(const void *ventry1, const void *ventry2)
{
char **entry1 = (char **)ventry1;
char *s1 = entry1[context.sortColumnIndex];
char **entry2 = (char **)ventry2;
char *s2 = entry1[context.sortColumnIndex];
return strcmp(s1, s2);
}
<强>更新强>
您可以扩展方法以提供您自己的自定义比较方法,如下所示:
struct sort_on_index_context_custom
{
size_t nRows;
size_t nColumns;
size_t sortColumnIndex;
int (*comparer)(const char *, const char *);
};
static int compare_custom(void *p_vcontext, const void *ventry1, const void *ventry2)
{
struct sort_on_index_context_custom *p_context = (struct sort_on_index_context_custom *)p_vcontext;
char **entry1 = (char **)ventry1;
char *s1 = entry1[p_context->sortColumnIndex];
char **entry2 = (char **)ventry2;
char *s2 = entry2[p_context->sortColumnIndex];
return p_context->comparer(s1, s2);
}
void sort_on_index_custom(char **objs, size_t nRows, size_t nColumns, size_t sortColumnIndex, int (*comparer)(const char *, const char *))
{
struct sort_on_index_context_custom context;
if (sortColumnIndex < 0 || sortColumnIndex >= nColumns)
return; /* Print an error or throw an exception! */
context.nColumns = nColumns;
context.sortColumnIndex = sortColumnIndex;
context.nRows = nRows;
context.comparer = comparer;
qsort_s(objs, nRows, sizeof(char *) * nColumns, compare_custom, (void *)&context);
}
然后像这样调用它来将给定的字符串列整数为整数:
static int integer_compare(const char *s1, const char *s2)
{
int int1 = atoi(s1);
int int2 = atoi(s2);
return int1 - int2;
}
sort_on_index_custom(&objs[0][0], nRows, nColumns, 1, integer_compare);