如何检查二进制文件是否包含某些预期数据?

时间:2015-03-19 19:29:48

标签: c

我正在创建一个小型数据库,其数据包含在二进制文件中。此时,程序仅读取文件中的数据或覆盖该数据。数据库由结构Database表示。问题是如果我在不检查数据是否存在的情况下正确读取文件,程序就会停止工作。这是它打印数据的方式:

        printf("nth of table: %d\n", table->id);
        printf("table name: %s\n", table->name);

我猜是因为id和name中没有数据,所以程序停止工作。如果我初始化struct数据库中的数据,这不会发生,但只有当我想覆盖数据库时才可以。

那么有没有办法检查从二进制文件中读取的数据是否符合我的预期 - > id =“something”?

或者从文件读取数据到数据库之类的结构的另一种方法是什么,并确保没有这样的问题?

以下是我的计划的相关代码。

        struct Database {
            int num_table;
            char *name;
            struct Table *table_list[MAX_TABLE]; // contains pointers to each table in the database


        };


        struct Table {
            int id; 
            int num_row;
            char *name;
            struct Row *row[MAX_ROW]; // pointer to each row in a table

        };

    struct Connection{
        FILE *file;
        struct Database *db;

    };

void load_db(struct Connection *conn){
    int result = fread(conn->db, sizeof(struct Database), 1, conn->file);
    if(!result)
        //printf("result%d", result);
        die("cannot load database");
}

        struct Connection *connect_db (char *file_name, char *mode){
            // allocate memory
            struct Connection *conn = malloc(sizeof(struct Connection));
            if(!conn)
                die("memory error with connection");
            conn->db = malloc(sizeof(struct Database));
            if(!(conn->db))
                die("memory error with database");

            // open stream and load database from the file
            if(strcmp(mode, "w") == 0){
                conn->file = fopen(file_name, mode);
                //load_db(conn); // load data from file
            }else if(strcmp(mode, "r") == 0){
                conn->file = fopen (file_name, mode);
                load_db(conn); // load data from file
            }else{
                die("incorrect mode");

            }

            return conn;

        }


        int print_record(char *table_name, struct Database *db){

            struct Table **table_list = db->table_list;
            struct Table *table;
            int all_num_table = db->all_num_table; // include those deleted
            int i = 0;



            if(strcmp(table_name, "all") == 0){ // assume users enter 'all' not 'All' or so on

                for (i; i < all_num_table; i++){
                    table = table_list[i];

                    if((table->id != -1) && ()){
                        printf("nth of table: %d\n", table->id);
                        printf("table name: %s\n", table->name);
                        printf("Number of rows: %d\n", table->num_row);
                        printf("Number of available rows: %d\n", (MAX_ROW - (table->num_row)));

                        printf("-----------------------------");

                        // record of each row is in here

                        printf("--------- End of table nth: %d ----------\n", table->id);
                    }

                }

            }else{


            }

        }

1 个答案:

答案 0 :(得分:0)

您的问题是:您正在阅读一个复杂的数据结构,该结构包含直接来自文件的指针作为二进制数据。

这种方法有几个缺点:

  • 如果数据结构包含指针,它只会读取指针的值,而不是指针指向的数据

  • 如果您在一台计算机上写入数据并在另一台计算机上访问它,则表示形式可能不同(例如,由于32位和64位计算机之间的差异)

不要这样做。你应该真正阅读有关序列化的内容。即如果要序列化char *字符串,可以先按网络字节顺序使用4个字节写入字符串的长度,然后写入字符串的各个字节。读取数据时,读取字符串长度,使用malloc()分配内存并读取各个字节。

不幸的是,您将需要比示例程序显示的更多代码行。例如。我最近为一个相当简单的数据结构编写了数据序列化和反序列化例程(虽然比你的更复杂),它们是1000行代码。

如果你不理解为什么数据结构原始读/写不起作用,那么你或许应该在这个时候使用与C不同的语言。 C代表专家。