C 按数字对2D字符数组进行排序

C 按数字对2D字符数组进行排序,c,arrays,sorting,pointers,C,Arrays,Sorting,Pointers,我一直在寻找解决方案,但似乎找不到与我类似的解决方案。我正在努力分类 由特定列组成的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]

我一直在寻找解决方案,但似乎找不到与我类似的解决方案。我正在努力分类 由特定列组成的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、 并将非常感谢帮助如何做到这一点


提前感谢。

在对由定义的“C”中的隐式结构进行排序时,每行对应一个对象,我发现使用它很有用,因为它允许我将有关要排序的数组项的更多信息传递到比较函数中

因此,下面的代码接受带有
nRows
行和
nColumns
列的二维字符串数组,并对
sortcolumnidex
指定的列进行排序。提供给
qsort_s()
的额外
context
指针将排序索引向下传递给排序方法,而不需要全局变量:

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);
}
编辑

如果在您的开发环境中没有
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);
}

您的
比较功能是什么?此外,使用结构数组似乎比使用双字符数组更为明显(特别是因为您已经为右侧定义了该结构)。此外,除了您的
compare\u函数
,如何定义结构
obj
指向?与mafso的评论相关:您正在为辅助数组中的前2个项目分配一个数字,这应该是指向字符的指针。这是行不通的(基本上,
char*objs[count][0]=
)。使
objs
成为一个结构数组。将
sizeof(char*)
传递给
qsort()
表明您对数组的维度感到困惑。comparator函数将获得传递到类型为
char*(*)[50]
的数组的指针
qsort_s()
不是标准的,仅在Windows上可用。你怎么知道OP在使用Windows?@顺磁性羊角面包-嗯,显然我不知道,尽管我在所有地方都做过可移植的“C”编码,有一个版本的“排序”可以使用额外的参数。如果OP没有该变量,他/她将被迫使用静态变量。
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);