c - 在c中按字母顺序对字符串数组进行排序

标签 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 结构

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

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

每次运行时我都会收到错误

最佳答案

您的代码存在一些问题:

首先:这看起来根本不对:

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 .namechar[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成员(member)下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_numj < l_num以避免使用未初始化的字符串值。

最后一点提示:如果您没有处理任何对时间要求太高的事情,那么使用 calloc 可能会很有用。而不是malloc ,尤其是在处理字符串时,或使用 memset(temp[i]->name, 0, 20);确保所有char[]成员确实是空字符串。
如果您发现自己使用了很多str*函数( strncatstrncpy 等),甚至像 temp[i]->name[0] = '\0'; 这样简单的函数可以让生活变得更加轻松。

关于c - 在c中按字母顺序对字符串数组进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34545538/

相关文章:

c - 驱动程序 PsLookupProcessByProcessId 错误代码 0xc000000b

c# - 在数组中找到 FEW 最频繁的元素

C - 如何将 strcpy 用于二维数组?

Java:多维数组输出困惑?

java - 如何使用 1-1000 的整数创建 100 的数组?

java - 错误: Out of bounds Java Bubble sort

c - 球坐标转换的疑惑

谁能帮我找到这个 C 函数中的错误吗?

c - 数组初始化: a value of type "char *" cannot be used to initialize an entity of type "float"

javascript - 使用 Javascript 按字母顺序对 JSON 响应进行排序