C ++ qsort指针数组没有排序

时间:2010-03-04 17:53:00

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

我试图在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;
    }

2 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:1)

这个问题基本上归结为“你怎么知道你的可变长度记录的长度。”需要有一些方法可以告诉记录本身或其他一些数据。

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

在您的情况下,您可以通过查找char(10)来判断长度,因为您始终使用它们来终止字符串。你需要一个自定义比较(strcmp将无法工作 - 它需要NUL终止符),并且知道这一点。