【问题标题】:Why is the sorting of my array resulting in values being overwritten?为什么我的数组排序会导致值被覆盖?
【发布时间】:2021-10-29 07:35:16
【问题描述】:

我正在完成Beginning C, Fifth Edition,并且我正在做第 7 章末尾关于指针的练习。我正在进行的练习如下:

练习 7-2。编写一个程序,从键盘读取任意数量的谚语,并将它们存储在运行时分配的内存中。然后程序应该输出按长度排序的谚语,从最短的开始到最长的结束。

这是我的代码,其灵感来自于本书之前的示例:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

int main(void) {
    // Initialize variables
    int max_proverb_size = 100;
    char proverb[max_proverb_size];
    int count = 0;
    int capacity = 5;
    char **proverbs = calloc(capacity, sizeof(char*));
    char **tempPtr = NULL;
    char *tempP = NULL;
    size_t str_len = 0;
    bool sorted = false;
    
    printf("Please enter proverbs from the keyboard, and enter in nothing to stop.\n");
    
    char *ptr = NULL;
    
    // Read proverbs from keyboard
    while (true) {
        ptr = fgets(proverb, max_proverb_size, stdin);
    
        if (!ptr) {
            printf("Error reading proverb.\n");
            free(proverbs);
            proverbs = NULL;
            return 1;
        }
    
        if (*ptr == '\n') break;
    
        if (count == capacity) {
            capacity += 5;
    
            tempPtr = realloc(proverbs, capacity * sizeof(char*));
    
            if (!tempPtr) {
                printf("Error reallocating memory.");
                return 1;
            }
            proverbs = tempPtr;
        }

        str_len = strnlen(proverb, max_proverb_size) + 1;
        if (!(proverbs[count] = malloc(str_len))) return 2;
        strcpy(proverbs[count++], proverb);
    }

    // Sort proverbs by length
    while (!sorted) {
        sorted = true;
        size_t length_string1;
        size_t length_string2;
    
        for (size_t i = 0; i < count - 1; ++i) {
            length_string1 = strnlen(proverbs[i], max_proverb_size);
            length_string2 = strnlen(proverbs[i+1], max_proverb_size);

            if (length_string1 > length_string2) {
                sorted = false;
                tempP = proverbs[i];
                proverbs[i] = proverbs[i+i];
                proverbs[i+1] = tempP;
            }
        }
    }

    printf("Your proverbs ordered by their length are:\n");
    for (int i = 0; i < count; ++i) {
        printf("%s\n", proverbs[i]);
    }

    free(proverbs);
    proverbs = NULL;

    return 0;
}

我认为我对字符串的排序方式存在问题,特别是这部分:

if (length_string1 > length_string2) {
    sorted = false;
    tempP = proverbs[i];
    proverbs[i] = proverbs[i+i];
    proverbs[i+1] = tempP;
}

例如,如果我输入以下输入:

Please enter proverbs from the keyboard, and enter in nothing to stop.
Hello World
Bye
This is the longest string

然后我得到这个输出:

Your proverbs ordered by their length are:
Hello World

Hello World

This is the longest string

看来,当我的代码发现“Bye”和“Hello World”需要切换时,实际上是用“Hello World”覆盖了“Bye”。

我使用gdb 运行我的代码,并在切换这两个字符串时尝试单步执行代码,但我无法找出它为什么会这样。对此的任何帮助将不胜感激。提前致谢。

【问题讨论】:

  • 如果你担心排序问题,也许你可以使用标准的C函数qsort?
  • proverbs[i] = proverbs[i+i]; 里面不是 1,而是 i+i。
  • 感谢 cmets。 @dratenik 解决了这个问题,我不敢相信我错过了!我花了太多时间试图弄清楚这一点。非常感谢。另外,我将尝试 qsort 并将 for 循环更改为 i &lt; count - 2。
  • 注意:我发现它的语法突出显示“等等,那个看起来很奇怪”,您可以通过 SO 突出显示代码的方式看到它。
  • @500-InternalServerError i &lt; count -1 正常工作,而不是 i &lt; count - 2。你能解释一下为什么这么说吗?

标签: arrays c pointers


【解决方案1】:

正如 dratenik 在 cmets 中指出的那样,我错误地写了 proverbs[i] = proverbs[i+i] 而不是 proverbs[i] = proverbs[i+1]。更改该行解决了问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-29
    • 1970-01-01
    • 2018-04-09
    • 2020-05-12
    • 2012-05-29
    相关资源
    最近更新 更多