【问题标题】:C - Bubble Sort Program binary fileC - 冒泡排序程序二进制文件
【发布时间】:2017-04-12 14:30:40
【问题描述】:

我正在尝试在不使用任何数组的二进制文件中创建一个冒泡排序程序,而不是使用 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 部电影,我哪里错了?我能做什么?

【问题讨论】:

  • len 不是记录数。并且需要倒回每个内部循环。
  • 程序为什么要显示任何内容?我找不到任何printf 电话。
  • fseek(fd,-sizeof(Ficha_t),SEEK_SET); 必须始终在循环结束时完成
  • SEEK_SET 是文件的开头——我认为负偏移在那里没有意义。 SEEK_CUR 是当前位置
  • 现实生活中没有人会这样做。 a) 合并排序对文件来说已经更好了,b) mmap 无论如何都更快...

标签: c database bubble-sort


【解决方案1】:

如 cmets 中所述,您希望:

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

获取文件中的记录数。

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

我会为ftell(fd) / sizeof(Ficha_t) 添加一堆 printfs,这样您就可以看到它正在正确执行所有操作。此外,您可能正在检查您正在调用的函数的返回值(当您在开始之前尝试寻找并在那里读/写时,它们可能会返回错误)

【讨论】:

    【解决方案2】:

    具体代码示例:

    #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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      • 2015-09-13
      • 1970-01-01
      • 2014-03-26
      • 2018-11-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多