字符串数组上的冒泡排序不使用 strcmp 在 C 中执行任何操作

Bubble sort on string array not doing anything in C with strcmp

我正在尝试对C (char**) 中的字符串数组进行排序,字符串数组是目录中所有文件名的数组。 这是代码的所有部分,我希望代码按字母顺序对数组进行排序,但它不起作用。 这是从目录

获取文件的代码
typedef struct
{
    char** names;
    int32_t count;
} Files;

void swap(char* a, char* b)
{
    char* temp = a;
    a = b;
    b = temp;
}

void bubbleSort(char** strs, uint32_t length)
{
    uint32_t i = 0, j = 0;
    for (i = 0; i < length; i++)
    {
        for (j = 0; j < length - i - 1; j++)
        {
            if (strcmp(strs[j], strs[j + 1]) < 0)
            {
                swap(strs[j], strs[j + 1]);
            }
        }
    }
}

Files* getScannableFilesInDir(char* dirname)
{
    Files* files = (Files*)malloc(sizeof(Files));
    files->names = NULL; //clearing garbage values
    files->count = 0;    //clearing garbage values
    uint32_t dirnameLength = strlen(dirname);
    uint32_t count = 0;
    uint32_t countIterations = 0;
    DIR* d = opendir(dirname);
    struct dirent* dir = NULL;
    while ((dir = readdir(d)) != NULL)
    {
        if (files->names == NULL) //first file, if START_AMOUNT is set to 0 we want to allocate enough space for the first path, once we know there is at least 1 file
        {
            files->names = (char**)malloc(1 * sizeof(char*));
            count++; // there is enough space allocated for 1 string 
        }

        if (strcmp(dir->d_name, ".") && strcmp(dir->d_name, "..") && dir->d_type != DT_DIR)
        {
            ++countIterations;
            if (count < countIterations)
            {
                files->names = (char**)realloc(files->names, countIterations * sizeof(char*)); //adding 1 more space
            }
            files->names[countIterations - 1] = (char*)malloc(sizeof(char) * (strlen(dir->d_name) + dirnameLength) + 2); //-1 because we are incrementing at the start of the loop and not the end 
            //+ 2 at the end because a. the [=10=] at the end, b. 1 space for adding the slash
            strcpy(files->names[countIterations - 1], dirname);
            files->names[countIterations - 1][dirnameLength] = '/'; //changing the [=10=] to /
            strcpy(files->names[countIterations - 1] + (dirnameLength + 1), dir->d_name); //adding the name after the /, now we have the full name
        }
    }
    closedir(d);
    files->count = countIterations;
    bubbleSort(files->names, files->count);
    return files;
}

我检查了其余的代码,我没有在代码的任何其他位置更改文件->名称的值,只是阅读它。

你交换,以及从冒泡排序中调用它的方式都是错误的。首先让我教你一个简单的基础知识。

C 中的参数是 pass-by-value。更改作为参数传递给函数的参数的 caller-side 数据的唯一方法是更改​​参数的基本原理。你仍然会传递 by-value,你只需要使“值”成为你可以用来访问调用者的变量数据的东西。在 C 语言中,您可以通过将形式参数声明为 pointer-to-type、传递您想要更改的内容的地址 caller-side,并在函数内通过取消引用使用指针来发起更改。

void foo(int *a)
{
    *a = 42; // stores 42 in whatever 'a' points to
}

现在,让我们看看您的交换:

void swap(char* a, char* b)
{
    char* temp = a;
    a = b;
    b = temp;
}

好吧,我们有两个指针。但是在这段代码中,我们实际上并没有取消引用 anything。我们所做的只是在本地交换两个指针的值。来电者完全不受任何影响。

你的交换应该做的是交换两个 指针。我们有两个要交换的 char* 调用方值。这样做的方法与我们之前讨论的完全一样。声明形参为pointer-to-type(我们的类型是char*,所以我们的参数是char**),然后使用解引用修改caller-side数据。

void swap(char **ppA, char **ppB)
{
    char *pp = *ppA;
    *ppA = *ppB;
    *ppB = pp;
}

That 将交换两个指针,但前提是调用者将两个指针的地址传递给我们。注意这里的白话。我确实 而不是 说“将两个指针中的地址 传递给我们”(例如它们的值),我说“将地址传递给我们 of 两个指针”(例如,指针本身驻留在内存中的位置)。这意味着冒泡排序也需要改变:

void bubbleSort(char** strs, uint32_t length)
{
    uint32_t i = 0, j = 0;
    for (i = 0; i < length; i++)
    {
        for (j = 0; j < length - i - 1; j++)
        {
            if (strcmp(strs[j], strs[j + 1]) < 0)
            {
                swap(strs+j, strs+j+1); // <=== HERE
            }
        }
    }
}

这会将 str[j] str[j+1] 处的指针地址传递给交换函数。

这应该可以解决您的交换问题。算法是否正确,或者你的其余代码是否正确,我留给你消化。