C 对字符串排序并设置它

C 对字符串排序并设置它,c,pointers,C,Pointers,注:这是家庭作业 我需要对字符串进行排序,不允许更改此赋值的方法头 我已填写以下方法(使用适当的比较器): 如果我在最后打印输出,我会看到我期望的结果 该方法在for循环中的主函数内部调用如下: char* key = malloc(strlen(words[i]) + sizeof(char)); sortString(words[i], key); printf("key = %s\n", key); //key is blank 我不知道如何获取键以获得输出值。据我所知,我需要通过引用传

注:这是家庭作业

我需要对字符串进行排序,不允许更改此赋值的方法头

我已填写以下方法(使用适当的比较器):

如果我在最后打印输出,我会看到我期望的结果

该方法在for循环中的主函数内部调用如下:

char* key = malloc(strlen(words[i]) + sizeof(char));
sortString(words[i], key);
printf("key = %s\n", key); //key is blank

我不知道如何获取
以获得输出值。据我所知,我需要通过引用传递,这需要sortString获取
char**output
,这样我就可以传入
&key
,但不幸的是,我无法更改方法头。。有没有其他我不知道的方法来实现这一点?

另一种方法是让
输出指向一个足够大的缓冲区,以容纳整个输入字符串。然后可以将排序后的字符串复制到该缓冲区中。看起来这就是您已经在做的事情。

您的排序会导致未定义的行为。(除非要传递的字符串后面有两个空字符,否则这是不可能的。此外,如果比较器先对较大的字符进行排序,则也不会有问题。)

这里发生了什么: 问题是我们有一块内存,其中包含以下字节:

{'h', 'e', 'l', 'l', 'o', '\0')
您对qsort的调用将导致:

{'\0', 'e', 'h', 'l', 'l', 'o'}
然后递增输出指针,然后打印
{'e','h','l','l','o'}
,该不是以null结尾的。这是未定义的行为

此外,在调用
之后,键
指向
{'\0',e',h',l',l',o'}
。由于
output
是一个局部变量,因此不会执行输出指针的增量

因此,当您尝试打印
键时,该字符串的第一个字符是空字符,这意味着它打印空字符串

让我们解决这个问题: 那么,要称之为这一点,我们将做:

int main() {
    const char * words[] = {
        "hello",
    };

    char *key = malloc(strlen(words[0]) + 1);
    sortString(words[0], key);

    printf("%s -> %s\n", words[0], key);
}   
我们什么时候需要传递
qsort(单词[0],&key)

如果要让
sortString()
dest

分配内存,则只需通过指针传递指针(因此是
char**
),无需将指针传递给指针。通过引用传递意味着传递指针,而字符串已经是指针了。你做的很好?问题是什么。嗯,我想做的是分配一个额外1个字符的字符串,然后将空终止符插入其中,但现在看,我做的是愚蠢的。谢谢你的深入解释!我现在很清楚这一点。作为参考,我的qsort实际上是从最小到最大(a->z)排序的,所以空终止符是否在正确的位置?
qsort()
不应该在正确的代码版本中移动空终止符。您在问题中的版本确实移动了它,这就是未定义行为的来源。如果您在我发布的代码中注意到,对
qsort()
的调用不包括字符串中包含
'\0'
的位置。
void sortString(const char* input, char* output) {
    strcpy(output, input);
    qsort(output, strlen(output), sizeof(char), comparator);
}
int main() {
    const char * words[] = {
        "hello",
    };

    char *key = malloc(strlen(words[0]) + 1);
    sortString(words[0], key);

    printf("%s -> %s\n", words[0], key);
}