Сортировка массива строк в алфавитном порядке с использованием указателей - PullRequest
0 голосов
/ 14 марта 2020

У меня есть проект, в котором я должен создать программу, которая позволит пользователям вводить имена в любом порядке. Затем программа отображает имена в алфавитном порядке. Также все это должно быть сделано с помощью указателей. Теперь моя попытка программы побуждает пользователя вводить имена и отображает их, но по какой-то причине я не могу их отсортировать. Может кто-нибудь помочь мне?

Вот моя попытка программы:

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

int main() {
  int list;
  char *names[20];
  char str[20];
  printf("Enter the number of names: ");
  scanf("%d", &list);
  fflush(stdin);
  for (int i = 0; i < list; i++) {
    printf("Enter name %d: ", i + 1);
    // gets(str);
    scanf("%[^\t\n]s", str);
    fflush(stdin);
    names[i] = (char *)malloc(strlen(str) + 1);
    strcpy(names[i], str);
  }
  void sortNames();
  for (int i = 0; i < 5; i++)
    printf("%s\n", names[i]);
  return 0;
}

void sortNames(char **name, int *n) {
  int i, j;
  for (j = 0; j < *n - 1; j++) {
    for (i = 0; i < *n - 1; i++) {
      if (compareStr(name[i], name[i + 1]) > 0) {
        char *t = name[i];
        name[i] = name[i + 1];
        name[i + 1] = t;
      }
    }
  }
}

int compareStr(char *str1, char *str2) {
  while (*str1 == *str2) {
    if (*str1 == '\0' || *str2 == '\0')
      break;

    str1++;
    str2++;
  }
  if (*str1 == '\0' && *str2 == '\0')
    return 0;
  else
    return -1;
}

Ответы [ 2 ]

1 голос
/ 14 марта 2020

Проблема здесь в том, что функция compareStr никогда не вернет значение больше 0. Она просто скажет вам, схожи ли 2 строки.

Для сортировки, вам нужно добавить дополнительный лог c следующим образом:

int compareStr(char *str1, char *str2) {
    while (*str1 == *str2) {

        if (*str1 == '\0' || *str2 == '\0')
            break;

        str1++;
        str2++;
    }
    if (*str1 == '\0' && *str2 == '\0'){
        return 0;
    }
    else if(*str1 > *str2){
        return 1;
    }else{
        return -1;
    }
}

Кроме того, вы должны вызвать функцию sortNames как sortNames (names & & list) и убедитесь, что определения функций написаны в правильном порядке, или используйте объявления функций.

1 голос
/ 14 марта 2020

Сосредоточив внимание только на проблемах с сортировкой, основной является то, что вы никогда не вызываете функцию сортировки, которую вы определяете позже. Строка

void sortNames();

служит только для объявления функции с идентификатором sortNames, которая принимает любое количество аргументов любых типов (вероятно, не совсем то, что вы хотите сделать). Я бы порекомендовал изменить эту строку на

sortNames(names, list); // Not &list because I'm about to suggest not taking it as a pointer

Тогда для самой функции sortNames мне не совсем понятно, почему вы берете длину массива для сортировки в качестве указателя вместо просто передавая int сам. Я бы порекомендовал изменить эту функцию на

void sortNames(char **name, int n) {
  int i, j;
  for (j = 0; j < n - 1; j++) {
    for (i = 0; i < n - 1; i++) {
      if (compareStr(name[i], name[i + 1]) > 0) {
        char *t = name[i];
        name[i] = name[i + 1];
        name[i + 1] = t;
      }
    }
  }
}

Одна проблема с этим в том виде, в каком она есть, заключается в том, что выражение compareStr(name[i], name[i + 1]) > 0 всегда ложно. Это связано с тем, что compareStr возвращает только 0 или -1. Вы можете исправить это, переписав compareStr, чтобы правильно обработать случай, когда *str1 > *str2. Один из возможных способов сделать это может быть

int compareStr(char *str1, char *str2) {
    if (*str1 == '\0' && *str2 == '\0') {
        return 0;
    } else if (*str1 > *str2) {
        return 1;
    } else if (*str1 < *str2) {
        return -1;
    }
    return compareStr(str1 + 1, str2 + 1);
}

Хотя, если вы пишете это для изучения, я бы предложил попробовать пересмотреть ваше текущее итеративное решение, а не просто копировать и вставлять эту версию.

Наконец, поскольку вы хотите использовать эти функции до того, как определили их, вы должны либо переместить их определения до того момента, когда они используются (т. Е. Иметь compareStr, затем sortNames и затем main), либо предоставить предварительное объявление в начале вашего файла для этих функций, т.е. добавьте

void sortNames(char **name, int n);
int compareStr(char *str1, char *str2);

над main.


Как уже отмечали другие, вы, вероятно, хотите избежать fflush(stdin) как его неопределенное поведение, и я бы рекомендовал против приведение к результату malloc.

...