【问题标题】:Using qsort in C on an array of strings在 C 中对字符串数组使用 qsort
【发布时间】:2015-06-24 03:19:36
【问题描述】:

我不知道如何使用 qsort。我想对字符串数组进行排序。像这样:

John              Adam
Adam      ->      John
Stacy             Stacy

但是,我所做的一切似乎都不起作用。我已经尝试完全复制其他人使用的内容(来自各种来源的大约 5 个不同的 qsort 函数),但没有任何效果。我有一个适用于 int 的有效方法(向后但至少有效)。

这是我拥有的必要代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct {
char name[80];
int age;
} RECORD;
RECORD record[25];

int main (int argc, char *argv[80]){     // Using command line to get my strings

    int i = 2, j;
    for(j = 0; j < (argc / 2); j++)      //Converting and storing my ages
    {
        record[j].age = atoi(argv[i]);
        i = i + 2;
    }

    int p, q = 1;
    for(p = 0; p < (argc / 2); p++)
    {
        strcpy(record[p].name, argv[q]);
        q = q + 2;
    }
}

int compareByName(const void* a, const void* b) //The qsort that doesn't work at all
{
    const char *ia = (const char *)a;
    const char *ib = (const char *)b;

    return strncmp(ia, ib, 25);
}

int compareByAge (const void * a, const void * b)  //My other qsort that works backwards
{

    RECORD *RECORDA = (RECORD *)a;
    RECORD *RECORDB = (RECORD *)b;

    return ( RECORDB->age - RECORDA->age );
}

void printRecords(RECORD r[], int num){
//printing stuff here

double size = sizeof r[0];
double count = sizeof(r)/size;          //My qsort with size stuff, doesn't work
qsort(r, count, size, compareByName);   // if I do it the same as the other  

qsort (r, 25, sizeof(RECORD), compareByAge);   //My other qsort that works backwards

//more printing stuff here
}

【问题讨论】:

  • 不是说年龄可能溢出,而是为了避免溢出使用(RECORDB-&gt;age &gt; RECORDA-&gt;age) - (RECORDB-&gt;age &lt; RECORDA-&gt;age)

标签: c arrays sorting qsort


【解决方案1】:

您没有字符串数组,您有一个RECORDs 数组,听起来您想根据记录的name 数组中的字符串对该数组进行排序。所以你想要这样的东西:

int compareByName(const void *a_, const void *b_) {
    RECORD *a = a_, *b = b_;

    return strcmp(a->name, b->name);
}

然后你用

排序
qsort (r, 25, sizeof(RECORD), compareByName);

【讨论】:

    【解决方案2】:

    好的,我发现这里有几个问题。

    值得注意的是,sizeof 是在编译时评估的,因此您不能使用 sizeof(r) 来确定传递给您的动态大小数组的大小。我猜这就是为什么num 被传递给printRecords

    正如@Chris 指出的那样,您正在对RECORD 结构而不是字符指针进行排序,因此比较函数和qsort 调用都需要考虑到这一点。

    您在年龄比较中将减法反转-如果左侧小于右侧,则需要返回负数,因此请使用RECORDA-&gt;age - RECORDB-&gt;age

    【讨论】:

      【解决方案3】:

      首先(这就是你的字符串没有排序的原因),double count = sizeof(r)/size; 是错误的。 sizeof(r) 没有按照您的预期进行。您需要将数组的大小传递给 printRecords(),如本问题所述:

      How to get the length of array in C? is "sizeof" is one of the solution?

      第二次, int compareByAge (const void * a, const void * b) //My other qsort that works backwards 是倒退的,因为你是倒退的。比较器函数总是返回 A - B,而不是 B - A。

      【讨论】:

      • 谢谢,我解决了 sizeof 问题。当我用RECORDA-&gt;age - RECORDB-&gt;age 替换RECORDB-&gt;age - RECORDA-&gt;age 时,qsort 完全停止工作并为我的打印功能提供空白数据。与我现在工作的名称 qsort 相同。如果我尝试以正确的方式翻转它们,它们会给出空白数据。
      猜你喜欢
      • 2011-05-02
      • 2013-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-12
      • 2010-12-20
      • 2012-09-09
      • 2011-07-19
      相关资源
      最近更新 更多