0

我正在尝试在 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;
    }
4

2 回答 2

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);
}
于 2010-03-04T18:07:38.420 回答
1

这个问题基本上归结为“你怎么知道你的可变长度记录的长度”。需要有某种方式来判断,要么从记录本身,要么从其他一些数据。

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

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

于 2010-03-04T18:08:22.433 回答