类项目涉及对字符串数组进行排序,每个字符串包含相同数量的列,如下所示:
Cartwright Wendy 93 Williamson Mark 81 Thompson Mark 100 Anderson John 76 Turner Dennis 56
程序接受一个命令行参数,要对哪个列进行排序,并且应该打印出未修改的已排序字符串。
我想使用strtok将每个字符串的副本分解为列,并为每一行创建结构,如下所示:
struct line {
char * line;
char column_to_sort_on[MAX_COLUMN];
}
我的问题出在qsort作为arg的比较函数指针中。如果我理解正确,比较函数必须将两个const void指针带到要排序的项,并返回一个int。这意味着我无法将指向结构的指针传递给比较函数,因为这不是qsort将要排序的内容。我无法传入列号来排序比较函数,因为它只能取两个参数。如何根据特定列对这些字符串进行排序?
编辑:如果我真的想要,排序仅限于qsort或我自己。给出选择,我选择qsort。 :)
编辑#2:协商一致似乎要么使用列号的全局变量,要么只使用qsort对结构数组进行排序。我没有想过只是对结构进行排序,并使用其中的指针打印出原始字符串。我想这就是我要做的。感谢大家的帮助!
答案 0 :(得分:2)
假设您不限于使用qsort,您可以使用std :: sort,以及存储列号的functor对象。如果你必须使用qsort,一个快速而肮脏的解决方案是将列号存储在一个全局变量中,并在comparisson函数中使用它。
答案 1 :(得分:2)
不同的比较器函数,所有这些函数都采用整个结构,但每个函数只使用一列进行比较。
答案 2 :(得分:2)
您可以传递这样的结构:
struct line {
char * line;
char column_to_sort_on[MAX_COLUMN];
}
...
line* Lines[max_lines]; // here you store the structs
int
cmp_lines( const void *elem1, const void *elem2 )
{
line* line1 = *(line**)elem1;
line* line2 = *(line**)elem2;
// do the comparisons
}
qsort(Lines, max_lines, sizeof(line*), cmp_lines);
答案 3 :(得分:1)
C ++或C?根据你的标签,我认为它是C ++。我们试试STL吧。
您应该使用std::sort
代替qsort
。 std::sort
不仅可以使用函数指针(与其C替代),还可以使用任何可以作为函数调用的对象。您可能知道可以使用operator()
将类实例称为函数。然后解决方案很简单:创建一个“functor”类,它将在构造时创建不同的功能。然后排序调用看起来像这样:
std::sort(array, array+size, comparator(2 /* sort by column #2 */));
仿函数类有效地创建了一个所谓的“闭包”:一个动态创建的功能对象,它具有局部变量,但不与这种方式创建的其他功能对象共享。它看起来像这样:
class comparator{
private: unsigned int field_n;
public: comparator(unsigned int _field_n) : field_n(_field_n) {};
public: int operator () (char const * lhs, char const * rhs)
{ /* compare here fields with index field_n */ };
};
请注意,代替void指针比较“function”(即您创建的类实例)具有char *
个参数,因此您不必为类型转换而烦恼。
在C中,遗憾的是,除了创建全局变量之外,你不能这样做。