C - 冒泡排序程序二进制文件

时间:2017-04-12 14:30:41

标签: c database bubble-sort

我试图在不使用任何数组的情况下在二进制文件中创建冒泡排序程序,而不是使用fseek和fwrite函数。

这是我的代码:

      typedef struct{  //Films
         short int year;
         char title[LEN_NAME];
         Genero_t gendre;
         float rateIMDB;
      }Ficha_t;

      FILE * fd;
      fd = fopen(name,"r+b");    
      Ficha_t aux1;
      Ficha_t aux2;
      int i,j,len;

        if (fd != NULL)
        {

        rewind(fd);
        fseek(fd, 0, SEEK_END);
        len=ftell(fd);
        rewind(fd);

        for(i=0;i<len;i++); 
        {
        for(j=0;j<len-1;j++)
        {

          fread(&aux1,sizeof(Ficha_t),1,fd);
          fread(&aux2,sizeof(Ficha_t),1,fd);

          if(strcmp(aux1.title,aux2.title)<0)
          {

            fseek(fd,-sizeof(Ficha_t)*2,SEEK_SET); //returning 2 positions for overwriting
            fwrite(&aux2, sizeof(Ficha_t), 1, fd);
            fwrite(&aux1, sizeof(Ficha_t), 1, fd);  
            fseek(fd,-sizeof(Ficha_t),SEEK_SET); //returning 1 position for checking again with the next film

          }
         }
        }
       }

它没有工作,因为它展示了同样的2部电影,我哪里错了?我该怎么办?

2 个答案:

答案 0 :(得分:0)

如评论中所述,您需要:

len=ftell(fd) / sizeof(Ficha_t);

获取文件中的记录数。

如果您尝试使用当前位置的偏移量进行搜索,请使用SEEK_CUR,而不是SEEK_SET

我会为ftell(fd) / sizeof(Ficha_t)添加一堆printfs,这样你就可以看到它正确地做了一切。此外,您可能正在检查您正在调用的函数的返回值(它们可能在您尝试在开始之前搜索并在那里读/写时返回错误)

答案 1 :(得分:0)

具体代码示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

void fbubble_sort(const char *filename, size_t rec_size, bool (*needSwap)(const void *, const void *)){
    FILE *fp = fopen(filename, "r+b");
    if(!fp){
        perror("fopen, r+");
        exit(EXIT_FAILURE);
    }
    void *first  = malloc(rec_size);
    void *second = malloc(rec_size);
    if(!first || !second){
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    enum { NO_SWAP = -1};

    long last_swap_pos;
    do {
        rewind(fp);
        long pos_1 = 0;//first record position
        last_swap_pos = NO_SWAP;
        if(0==fread(first, rec_size, 1, fp))
            break;
        while((pos_1 <= last_swap_pos || last_swap_pos == NO_SWAP) && 1==fread(second, rec_size, 1, fp) ){
            if(needSwap(first, second)){
                fseek(fp, pos_1, SEEK_SET);
                fwrite(second, rec_size, 1, fp);
                fwrite(first,  rec_size, 1, fp);
                fflush(fp);
                last_swap_pos = pos_1;
            } else {
                //exchange buffer
                void *temp = first;
                first = second;
                second = temp;
            }
            pos_1 += rec_size;
        }
    }while(last_swap_pos != NO_SWAP);

    free(first);free(second);
    fclose(fp);
}

#define DATA_FILE "test.dat"
#define GREATERi(type, member)\
bool greater_i(const void *first, const void *second){\
    return ((type*)first)->member > ((type*)second)->member;\
}\
/**/
#define GREATERs(type, member)\
bool greater_s(const void *first, const void *second){\
    return strcmp((type*)first)->member, ((type*)second)->member) > 0;\
}\
/**/
#define LESSi(type, member)\
bool less(const void *first, const void *second){\
    return ((type*)first)->member < ((type*)second)->member;\
}\
/**/

typedef struct {
    unsigned v;
} Record;

GREATERi(Record, v)

int main(void){
    void make_test_data(void);
    void print_test_data(void);

    make_test_data();
    print_test_data();

    fbubble_sort(DATA_FILE, sizeof(Record), greater_i);

    print_test_data();
}

void make_test_data(void){
    FILE *fp = fopen(DATA_FILE, "wb");
    if(!fp){
        perror("fopen, w");
        exit(EXIT_FAILURE);
    }
    Record rec;
    for(int i = 0; i < 100; ++i){
        rec.v = rand() % 100;
        fwrite(&rec, sizeof(rec), 1, fp);
    }
    fclose(fp);
}
void print_test_data(void){
    FILE *fp = fopen(DATA_FILE, "rb");
    if(!fp){
        perror("fopen, r");
        exit(EXIT_FAILURE);
    }
    Record rec;
    int cnt = 0;
    while(fread(&rec, sizeof(rec), 1, fp)){
        if(cnt)
            putchar(' ');
        printf("%2u", rec.v);
        if(++cnt == 10){
            putchar('\n');
            cnt = 0;
        }
    }
    putchar('\n');
    fclose(fp);
}