使用动态数组按字母顺序对单词进行排序

Sort words alphabetically using dynamic arrays

我在 C Programming: A Modern Approach 中遇到了一个问题,内容如下。

我正在使用 stdlib.h 中的 qsort,这是我目前拥有的:

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

#define MAX_LEN 20

int read_line(char str[], int n);
static int cmp(const void *p1, const void *p2);
int main()
{

  char *words[MAX_LEN];
  int i = 0, j;
  char word_str[MAX_LEN + 1], s[20];

  for (;;)
    {
      printf("\nEnter a word:  ");
      fgets(s, 20, stdin);
      if (strcmp(s, "\n") == 0)
          break;
      read_line(word_str, MAX_LEN);
    }

  int len = strlen(word_str);
  words[i] = malloc(len + 1);
  strcpy(words[i], word_str);

  qsort(words, len, sizeof(char *), cmp);

  printf("\nIn sorted order:  ");
  for (j = 0; j < len; j++)
    printf("%s ", words[j]);

  printf("\n");

  return 0;

}

int read_line(char str[], int n)
{
  int ch, i = 0;

  while ((ch = getchar()) != '\n')
    if (i < n)
      str[i++] = ch;
  str[i] = '[=10=]';
  return i;

}

static int cmp(const void *p1, const void *p2)
{

  return strcmp(* (char * const *) p1, * (char * const *) p2);

}

我收到的输出:

我被困在这一点上,因为我的编译器没有给我错误,在调试时我看到我的 word_str 是空的。

我是 c 的新手,所以请放轻松。

我在你的代码中发现了以下问题。

问题 1

words 中保存文本行的代码需要在 for 循环中。

for (;;)
{
  printf("\nEnter a word:  ");
  fgets(s, 20, stdin);
  if (strcmp(s, "\n") == 0)
      break;
  read_line(word_str, MAX_LEN);

  int len = strlen(word_str);
  words[i] = malloc(len + 1);
  strcpy(words[i], word_str);
}

问题2

您没有计数器来跟踪读取的行数。

使用:

int num_lines = 0;
for (;; ++num_lines)
{
  printf("\nEnter a word:  ");
  fgets(s, 20, stdin);
  if (strcmp(s, "\n") == 0)
      break;
  read_line(word_str, MAX_LEN);

  int len = strlen(word_str);
  words[num_lines] = malloc(len + 1);
  strcpy(words[num_lines], word_str);
}

问题3

您将第二个参数中的错误值传递给 qsort。您需要传递 num_lines,而不是最后一个字符串的长度。

qsort(words, num_lines, sizeof(char *), cmp);

问题4

打印排序后的字符串时,不要在 for 循环的条件中使用 len。请改用 num_lines

for (j = 0; j < num_lines; j++)
  printf("%s ", words[j]);