【问题标题】:C++ qsort array of pointers not sortingC ++ qsort指针数组未排序
【发布时间】:2010-03-04 17:52:59
【问题描述】:

我正在尝试在 C++ 中按字母顺序对充满可变长度记录的缓冲区进行排序。我之前问过如何实现这一点,并被告知要对指向记录的指针数组进行排序。我设置了一个指针数组,但意识到每个指针都指向记录的开头,但无法知道记录何时停止。当我尝试打印出数组中每个指针所指向的记录时,因此,对于每个指针,我都会得到所有记录的整个缓冲区,从指向的那个开始。 (例如,如果缓冲区包含“Helloworld”,并且每个字母都有一个指针,则打印指针数组将产生“Helloworldelloworldlloworldloworldoworldworldorldrldldd”。)显然,这不是我想要的;此外, qsort 似乎也没有在指针数组上工作。当我调试时,指针指向的内存空间似乎包含非常奇怪的字符,这些字符绝对不是 ascii 字符集的一部分,也不包含在我的输入文件中。我很迷茫。以下是我的代码;我怎么能做到这一点而不会得到我现在得到的奇怪结果?非常感谢,bsg。

int _tmain(int argc, _TCHAR* argv[])
{
    //allocate memory for the buffer
    buff = (unsigned char *) malloc(2048);
    realbuff = (unsigned char *) malloc(NUM_RECORDS * RECORD_SIZE);

fp = fopen("postings0.txt", "r");
        if(fp)
        {
            fread(buff, 1, 2048, fp);
            /*for(int i=0; i <30; i++)
                cout << buff[i] <<endl;*/

            int y=0;

 //create a pointer to an array of unsigned char pointers
    unsigned char *pointerarray[NUM_RECORDS];
    //point the first pointer in the pointer array to the first record in the buffer
            pointerarray[0] = &buff[0];
            int recordcounter = 1;  



        //iterate through each character in the buffer; 
    //if the character  is a line feed (denoting a new record),
// point the next pointer in the pointer array to the next 
//character in the buffer (that is, the start of the next record)
                for(int i=0;i <2048; i++)
            {
                if(buff[i] == char(10))
                {
                    pointerarray[recordcounter] = &buff[i+1];
                    recordcounter++;
                }


    }

//the actual qsort (NUM_RECORDS is a constant declared above; omitted here)
    qsort(pointerarray, NUM_RECORDS, sizeof(char*), comparator);

        }

        else 
            cout << "sorry";

        cout << sizeof(pointerarray)/sizeof(char*);
    for(int k=0; k < sizeof(pointerarray)/sizeof(char*);k++)
    {
        cout << pointerarray[k];
    }

int comparator(const void * elem1, const void * elem2)
{

    //iterate through the length of the first string
    while(*firstString != char(10))
    {
        return(strcmp(firstString, secondString));

                firstString++;
        secondString++;

        /       
    }
return 0;
    }

【问题讨论】:

  • 在我看来更像 C 而不是 C++...
  • 你的比较器函数是非常错误的 - 想想你在这里实际上想做什么。
  • 为什么你使用 _tmain 而在其余代码中直接使用 char?

标签: c++ pointers comparator variable-length qsort


【解决方案1】:

我猜问题出在您的比较器函数中(未按发布的那样编译)。 qsort 将指向数组元素的指针指向比较器函数。在您的情况下,这将是一个 指针 存储在数组中的char*

qsort 的手册页给出了这个例子:

static int
cmpstringp(const void *p1, const void *p2)
{
    /* The actual arguments to this function are "pointers to
      pointers to char", but strcmp(3) arguments are "pointers
       to char", hence the following cast plus dereference */

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

int
main(int argc, char *argv[])
{
    int j;

    assert(argc > 1);

    qsort(&argv[1], argc - 1, sizeof(char *), cmpstringp);

    for (j = 1; j < argc; j++)
        puts(argv[j]);
    exit(EXIT_SUCCESS);
}

【讨论】:

    【解决方案2】:

    这个问题基本上归结为“您如何知道可变长度记录的长度”。需要通过某种方式来判断,无论是从记录本身,还是从其他一些数据。

    一种方法是使用指针/长度对来引用记录——一个指向记录开头的指针和一个长度(int 或 size_t),它们一起存储在一个结构中。使用 C++,您可以使用 std::pair,或者使用 C 定义一个小结构。然后,您可以对这些数组使用 qsort。

    在您的情况下,您可以通过查找 char(10) 来判断长度,因为您总是使用它们来终止您的字符串。您需要一个意识到这一点的自定义比较(strcmp 不起作用 - 它需要 NUL 终止符)。

    【讨论】:

      猜你喜欢
      • 2021-09-20
      • 1970-01-01
      • 2015-12-13
      • 1970-01-01
      • 2014-07-04
      • 1970-01-01
      • 1970-01-01
      • 2021-08-02
      相关资源
      最近更新 更多