gcc (GCC) 4.7.0
c89
您好,
我尝试使用fwrite将行数据库保存到文件(db.dat)以编写它并使用fread检索它。但是,当我用fread检索它时,数据是空的。
我不确定在获取数据之前是否应该使用malloc。我在我的例子中试过了
我这里没有显示可用内存,因为这只是代码片段。
非常感谢任何建议,
This is my structure of the database:
struct address {
int id;
int set;
char *name;
char *email;
};
struct database {
struct address **rows;
size_t data_size;
size_t max_size;
};
struct connection {
FILE *fp;
struct database *db;
};
数据库打开:
struct connection* database_open(const char *filename, char mode)
{
struct connection *conn = NULL;
conn = malloc(sizeof(struct connection));
conn->db = malloc(sizeof(struct database));
if(conn->db == NULL) {
log_exit("Memory error allocating database", conn);
}
if(conn == NULL) {
log_exit("Memory error allocating connection", conn);
}
printf("Create a new database\n");
conn->fp = fopen(filename, "w");
if(conn->fp == NULL) {
log_exit("Failed to open file", conn);
}
return conn;
}
创建数据库:
void database_create(struct connection *conn, int _max_size, int _data_size)
{
int i = 0;
struct address *db_row = NULL;
/* Set the size of the database by assigning the max number of database rows */
conn->db->max_size = _max_size;
conn->db->data_size = _data_size;
/* Allocate memory for rows and size */
conn->db->rows = malloc(sizeof(struct address) * _max_size);
if(!conn->db->rows) {
log_exit("Memory error alocating rows", conn);
}
for(i = 0; i < _max_size; i++) {
db_row = malloc(sizeof(struct address));
db_row->id = i;
db_row->set = 0;
db_row->name = malloc(_data_size);
db_row->email = malloc(_data_size);
/* Add the row to the database */
conn->db->rows[i] = db_row;
}
}
编写数据库
void database_write(struct connection *conn)
{
rewind(conn->fp);
if(fwrite(conn->db, sizeof(struct database), 1, conn->fp) != 1) {
log_exit("Failed to write to database.", conn);
}
if(fflush(conn->fp) != 0)
{
log_exit("Cannot flush database.", conn);
}
}
然后我打开r +数据库并使用fread。但是,我在id和set变量中设置的数据是空的。
void database_load(struct connection *conn)
{
/* Clear any errors from file pointer */
clearerr(conn->fp);
/* I have had to hack this just so that I can get the
memory allocated before filling the structure not sure if this is the best way */
conn->db->rows = malloc(sizeof(struct address) * 1); /* This would be set to how many rows I have - just experimenting with just one */
conn->db->rows[0] = malloc(sizeof(struct address));
conn->db->rows[0]->name = malloc(20);
conn->db->rows[0]->email = malloc(20);
if(fread(conn->db, sizeof(struct database), 1, conn->fp) != 1) {
if(feof(conn->fp) != 0) {
log_exit("Database end of file", conn);
}
if(ferror(conn->fp) != 0) {
log_exit("Database cannot open", conn);
}
}
}
====编辑===
int main(int argc, char **argv)
{
char *filename = NULL;
char action = 0;
int id = 0;
int rows = 0;
int size = 0;
struct connection *conn = NULL;
if(argc < 3) {
log_exit("USAGE: ex17 <dbfile> <action> [ action params ]", conn);
}
filename = argv[1];
action = argv[2][0];
rows = atoi(argv[3]);
size = atoi(argv[4]);
conn = database_open(filename, action);
if(argc > 3) {
id = atoi(argv[3]);
}
switch(action) {
case 'c':
database_create(conn, rows, size);
database_write(conn);
break;
case 's':
if(argc != 6) {
log_exit("Need id, name, email to set", conn);
}
database_set(conn, id, argv[4], argv[5]);
database_write(conn);
break;
default:
log_exit("Invalid action, only: c = create, g = get, d = del, l = list", conn);
}
database_close(conn);
return 0;
}
答案 0 :(得分:1)
看到你的rows
是一个双指针,你需要用sizeof(pointer*)
初始化第一个指针,这个:
conn->db->rows = malloc(sizeof(struct address) * 1);
应该是:
conn->db->rows = malloc(sizeof(struct address*)); //notice how struct address becomes struct address*
与此相同:
conn->db->rows = malloc(sizeof(struct address) * _max_size);
应该是:
conn->db->rows = malloc(sizeof(struct address*) * _max_size);