【问题标题】:Sorting strings with qsort does not work使用 qsort 对字符串进行排序不起作用
【发布时间】:2015-04-02 20:36:27
【问题描述】:

我有一个程序,它询问几个字符串并应该对它们进行排序。 我的代码是:

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

#define MAX_STR_LEN 256

int myStrCmp (const void * a, const void * b)
{
    return strcmp((const char *)a, (const char *)b);
}

int main(void) 
{
    int strNum; // expected number of input strings
    int strCnt; // counter of strings
    char ** storage; // pointr to the memory when strings are stored
    char strBuf[ MAX_STR_LEN]; // buffer for strings
    char * strPtr; 
    // input of strings number
    do{
        printf("How many strings will be entered: ");
        while( scanf("%d", &strNum) != 1)
        {
            printf("ERROR: Not number was entered!\n");
            while( getchar() != '\n' );
            printf("Please enter a number: ");
        }
        if( strNum < 2 )
        {
            printf("ERROR: Number less than 2 was entered!\n");
        }
        while( getchar() != '\n' );
    }
    while(strNum < 2);
    // allocation of memory for pointers
    storage = (char **) calloc(strNum, sizeof(char*) );
    if( storage == NULL )
    {
        printf("ERROR: Unexpected problems with memory allocation!\n");
        return 1;
    }
    // input of strings
    for( strCnt = 0; strCnt < strNum; strCnt++)
    {
        printf("Enter string #%d:\n", strCnt + 1);
        fgets(strBuf,  MAX_STR_LEN, stdin);
        strPtr = strchr(strBuf, '\n');
        if( strPtr )
        {
            *strPtr = '\0';
        }
        else
        {
            strBuf[ MAX_STR_LEN - 1] = '\0';
        }
        // allocation memory for particular string
        storage[strCnt] = (char *) malloc(strlen(strBuf) + 1);
        if(storage[strCnt] == NULL)
        {
            printf("ERROR: Unexpected problems with memory allocation!\n");
            return 2;
        }
        // move string to dynamic memory 
        strcpy(storage[strCnt], strBuf);
    }
    // sort the strings
    qsort(storage, strNum, sizeof(char**), myStrCmp);
    // output the result
    printf("\nSorted strings:\n");
    for( strCnt = 0; strCnt < strNum; strCnt++)
    {
        printf("%s\n", storage[strCnt]);
    }
    return 0;
}

最简单的测试说明问题:

How many strings will be entered: 3
Enter string #1:
ddd
Enter string #2:
aaa
Enter string #3:
ccc

Sorted strings:
ddd
aaa
ccc

我尝试过 Visual C++ 和 gcc,但结果是一样的。请告诉我代码有什么问题?

【问题讨论】:

  • 嗨桑尼D!感谢您提供源代码和程序的示例运行。你在 StackOverflow 上的第一个问题比大多数人做得好得多。为了使您的问题变得更好,您可以做的一件事是对输入进行硬编码。在调用qsort() 之前有大量代码。您可以进入那里并对其进行硬编码,以便 storage 始终是相同的 5 个字符串。这会让你的问题真棒
  • 感谢您的建议。下一次,我会的。
  • 注意:与storage = (char **) calloc(strNum, sizeof(char*) );相比,storage = calloc(strNum, sizeof *storage);更易于编码和维护。

标签: c++ c qsort


【解决方案1】:

问题出在myStrCmp函数中。

因为ab不是简单数组中的元素,而是指针数组,所以它们的类型必须是char **,并且比较两个元素的函数必须如下:

int myStrCmp (const void * a, const void * b)
{
    return strcmp(*(const char **)a, *(const char **)b);
}

【讨论】:

  • 这个解决方案对我来说非常有效,尽管我不是 100% 确定我理解为什么在概念上需要如此。有人愿意尝试进一步解释吗?
  • 我将尝试通过关联示例来解释第二个 * 的需要。想象一下,你有苹果,然后按大小对它们进行排序(这是一个简单的例子,将不同手的 2 个手指同时指向的两个苹果与 2 个苹果进行比较),它们使任务变得更加复杂——你对一包苹果进行排序(因此要比较的对象是“对象包中的对象”,要到达苹果,您需要指向一个包(第一个 *),然后指向特定的苹果(第二个 *))。
  • 只要苹果像单个字符,字符串(数组)像苹果包,你可以想象strcmp就像一个天平,不用拆包就可以比较包。
  • 哇,出乎意料的有道理!非常感谢!
猜你喜欢
  • 2011-04-15
  • 2010-12-20
  • 1970-01-01
  • 1970-01-01
  • 2011-07-19
  • 2013-03-23
  • 1970-01-01
  • 2016-09-10
  • 1970-01-01
相关资源
最近更新 更多