【发布时间】: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 < count - 2。 -
注意:我发现它的语法突出显示“等等,那个看起来很奇怪”,您可以通过 SO 突出显示代码的方式看到它。
-
@500-InternalServerError
i < count -1正常工作,而不是i < count - 2。你能解释一下为什么这么说吗?