在c中按字母顺序排序字符串数组

时间:2015-12-31 11:07:14

标签: c arrays sorting

我有一个链接的srtings列表,我需要按字母顺序排序 我正在尝试将字符串复制到数组中,然后按字母顺序对它们进行排序和打印

void DisplayAll(k *l,p *p)
{
int i,j;
p *temp;
temp = malloc(l->num*sizeof *temp);
for (i = 0; i < l->num; i++)
{
    strcpy_s(temp[i].name, 20, p->name);
    p = p->next;
    i++;
}
for (i = 0; i < l->num - 1; i++){
    for (j = i + 1; j< l->num; j++)
    {
        if (strcmp(temp[i].name, temp[j].name) > 0)
        {
            strcpy_s(temp->name,20, temp[i].name);
            strcpy_s(temp->name[i],20, temp[j].name);
            strcpy_s(temp->name[j],20, temp->name);
    }
}

for (i = 0; i < l->num-1; i++){
    printf("%s\n", temp[i].name);
}
}

这是k结构和p stuct

typedef struct p
{
char name[20];
struct p* next;
}p;

 typedef struct k
   {
    int num;
    p *head;
   }k;

我得到一个错误evey时间我运行它

1 个答案:

答案 0 :(得分:2)

您的代码存在一些问题:

首先关闭 :这看起来并不正确:

strcpy_s(temp->name,20, temp[i].name);
strcpy_s(temp->name[i],20, temp[j].name);
strcpy_s(temp->name[j],20, temp->name);

根据the docs

errno_t strcpy_s(
   char *strDestination,
   size_t numberOfElements,
   const char *strSource 
);

第一个和最后一个参数应该是char*类型。您已将struct p .name定义为char[20],因此temp->name[i]的类型为char

我猜你实际上是在尝试做这样的事情:

//get struct p at offset i in temp, access member "name"
strcpy_s(temp[i].name, 20, temp[j].name);

其次 :您正在为temp分配内存,但是一旦完成,您就无法free(即函数返回)。换句话说,你有内存泄漏。当然,一旦你的程序退出,内存几乎肯定会被释放,但如果你正在编写必须长时间运行的程序,并且这样的函数被多次调用,你的内存消耗会逐渐消耗增加,你不希望这种情况发生。简而言之,在你的最后一个循环(你打印出来的所有东西)之后,添加:

free(temp);

修改

您现在已添加free来电,并且 - 正确地将其包裹在if (temp)中。但是:如果malloc返回了一个NULL指针,那么您认为在功能开始时您是不是应该这么做?

temp = malloc(l->num * sizeof *temp);
if (!temp)
    return;//or return int to indicate error or or exit EXIT_FAILURE; or something

没有理由让你在没有成功分配内存的情况下达到free(temp)的目的。

第三 :正如@Bluepixy在评论中所指出的那样,也存在语法错误:if (strcmp(temp[i].name, temp[j].name) > 0)分支从未正确关闭:你是在第三次strcpy_s电话后错过了一个结束括号。

最后 ,您正在分配足够的内存来容纳l->num结构。您初始化它们的方式是为每个其他结构分配一个列表中下一个name的{​​{1}}成员。你并没有真正确保struct p不是空指针。这可能会导致问题(取消引用空指针)。因此,将第一个循环更改为以下内容:

p->next

在此之后,使用int l_num = l->num;//you'll see why for (i = 0; i < l_num; i+=2)//increment twice if you want/need to { strcpy_s(temp[i].name, 20, p->name); p = p->next; if (p == NULL) { l_num = i+1;//this is as far as we ought to go in the subsequent loops break;//or handle error in some way } } ;i < l->num;替换循环中的所有i < l_num条件,以避免使用未初始化的字符串值。

只是最后一个提示 :如果您没有处理过于时间关键的事情,那么使用j < l_num代替{{1}可能会有用,尤其是在处理字符串时,或使用calloc确保所有malloc成员确实是空字符串。
如果您发现自己使用了很多memset(temp[i]->name, 0, 20);函数(char[]str*等),即使像strncat这样简单的事情也可以让生活变得更轻松。