从缓冲区读取可变长度记录 - 奇怪的内存问题

时间:2010-03-03 06:07:36

标签: c++ records fread qsort

我正在尝试在非常大的数据集上实现i / o密集型快速排序(C ++ qsort)。为了速度,我想一次将一大块数据读入缓冲区,然后使用qsort在缓冲区内对其进行排序。 (我目前正在处理文本文件,但很想转移到二进制文件。)但是,我的数据由可变长度记录组成,并且需要告诉qsort记录的长度以便排序。有没有办法将其标准化?我唯一能想到的就是相当复杂:我的程序当前从缓冲区读取,直到遇到换行符(ascii中的'10'),将每个字符转移到另一个数组。当它找到换行符(输入文件中的分隔符)时,它会使用空字符填充该记录的缓冲区中剩余的空格数(记录大小设置为30)。这样,我应该得到一个充满固定大小记录的缓冲区来给qsort。

我知道我的方法有几个问题,一个是它只是笨拙,另一个是记录大小可能大于30,但通常要少得多。有没有更好的方法呢?

同样,我目前的代码甚至不起作用。当我调试它时,似乎是将字符从一个缓冲区传输到另一个缓冲区,但是当我尝试打印出缓冲区时,它只包含第一条记录。

这是我的代码:

FILE *fp;
unsigned char *buff;
unsigned char *realbuff;
FILE *inputFiles[NUM_INPUT_FILES];
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;
    int recordcounter = 0;

    //cout << buff;
    for(int i=0;i <100; i++)
    {
        if(buff[i] != char(10))
        {
            realbuff[y] = buff[i];
            y++;
            recordcounter++;
        }        
        else
        {
            if(recordcounter < RECORD_SIZE)
                for(int j=recordcounter; j < RECORD_SIZE;j++)
                {
                    realbuff[y] = char(0);
                    y++;
                }
            recordcounter = 0;
        }
    } 

    cout << realbuff <<endl;   
    cout << buff;
}
else 
    cout << "sorry";

非常感谢, BSG

2 个答案:

答案 0 :(得分:1)

qsort函数只能在固定长度记录上工作(就像你说的那样)。为了对可变长度记录进行排序,您需要一个指向它们的指针数组,然后让qsort对指针数组进行排序。这也可能更有效,因为指针比大块数据移动要快得多。

std :: sort也是如此,建议使用它,因为它是类型安全的。请务必提供比较谓词(小于函数),将指针作为参数作为第三个参数。

答案 1 :(得分:0)

如何使用c++ file streams解析文件?

结帐此example(网站名称很奇怪,没有冒犯!!),将记录作为STL vector返回 然后你可以使用STL Sort algorithm