我试图在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;
}
答案 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终止符),并且知道这一点。