字符串数组上的冒泡排序不使用 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]
处的指针地址传递给交换函数。
这应该可以解决您的交换问题。算法是否正确,或者你的其余代码是否正确,我留给你消化。
我正在尝试对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]
处的指针地址传递给交换函数。
这应该可以解决您的交换问题。算法是否正确,或者你的其余代码是否正确,我留给你消化。