所以我要创建一个密码库,需要能够将HashTable保存到二进制文件,并在登录后将这些相同的内容从二进制文件读取回HashTable程序中
我一直在使用fwrite和fread玩了4个小时,似乎无法找到我要去的地方。目前,我正在进行段故障测试,我已经尝试了GDB来找到它,但是只得到消息:
Thread 2 received signal SIGSEGV, Segmentation fault.
0x00007fff9a9a16a0 in ?? ()
我用于读取文件的代码是:
void readFile(char * fileName, HTable * hashTable){
//Create file pointer and point it at fild to open
FILE * fp;
fp = fopen(fileName, "rb+");
//check if file exists
if(!fp){
printf("File could not be opened\n");
return;
}
//Set a temp Node to hold data, read data into the temp Node
//and insert temp into hashtable
Node * temp;
while(1){
fread(&temp, sizeof(Node), 1, fp);
insertData(hashTable, temp->key, temp->data);
if(feof(fp) != 0)
break;
printf("is this working?\n");
}
//Close file pointer
fclose(fp);
}
我写文件的代码是:
void saveFile(char * fileName, HTable * hashTable){
//Create a FILE pointer and point it to the file to open or create
FILE * fp;
fp = fopen(fileName, "wb+");
//If the file does not exist or cannot be created give error message
if(!fp){
printf("ERROR: File could not be created\n");
return;
}
//for each index of the hashTable write its contents to the file
for(int i = 0; i < hashTable->size; i++){
Node * temp = hashTable->table[i];
while(temp != NULL){
fwrite(&temp, sizeof(Node), 1, fp);
temp = temp->next;
printf("saved....\n");
}
printf("Index %d saved\n", i);
}
//Close file pointer
fclose(fp);
}
我知道segfault不是来自insertData函数,因为我已经对其进行了测试,并且知道它可以正常工作。对于我做错的最好的猜测是,关于我的写入条件的某些信息不正确,或者当我读取数据时,我在某处管理内存错误。
HashTable结构也是:
typedef struct HTable
{
size_t size;
Node **table;
void (*destroyData)(void *data);
int (*hashFunction)(size_t tableSize, char * key);
void (*printData)(void *toBePrinted);
}HTable;
我被击中的节点是:
typedef struct Node
{
char * key;
void *data;
struct Node *next;
} Node;
感谢您的任何反馈!
答案 0 :(得分:0)
首先,fwrite()/ fread()的参数1是 void * ,而不是** void ****。
第二,您不能使用 fwrite()/ fread()来保存/恢复数据,因为Node的成员{key,data}是指示额外内容的指针内存数据,但是使用fwrite()/ fread()只能操作指针{char *,void *,Node *},而不是多余的数据。
对于密钥,有一个示例:
Node n;
n.key = malloc(sizeof(char) * DEF_SIZE); // Suppose n.key = 0xb8b270
strcpy(n.key, "Hello world!");
fwrite(&n, sizeof(Node), 1, fp); // Only 0xb8b270 is written.
仅将字符串(n.key)的地址写入文件,而不是字符串“ Hello world”。你能听懂我说的话吗?
简而言之,fwrite()/ fread()只是写入/读取原始数据,当您的结构包含指示额外内存数据的指针时,请小心使用它们。
对于结构
typedef struct Item
{
char key[128];
char value[128];
struct Item *next;
} Item;
在这里使用fwrite()/ fread()可能是可以的,因为{char [],char [],Item *}将被写入/读取,只有{Item *}是无效数据,{char [],char []}可以正确保存/恢复。
在您的情况下,我想使用fprintf()/ fscanf()替换fwrite()/ fread()。
第三,有一个我的哈希映射实现,可以帮助您: https://github.com/foreverpersist/hashmap
答案 1 :(得分:-1)
这是一些代码。它可以编译,但是我还没有测试。我会完蛋,但我必须睡觉。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <malloc.h>
typedef struct Node
{
char * key; //assuming this is null terminated
void *data;
int datasize; //number of bytes in data
Node *next; //is this actually necessary?
} Node;
typedef struct HTable
{
size_t size;
Node *table;
void(*destroyData)(void *data);
int(*hashFunction)(size_t tableSize, char *key);
char *(*printData)(void *data);
} HTable;
void writenode(FILE* fp, Node *node) {
fprintf(fp, "%s\n", node->key);
fprintf(fp, "%d\n", node->datasize);
fwrite(node->data, sizeof(char), node->datasize, fp);
}
void readnode(FILE* fp, Node *node) {
char buffer[5001];
int len;
//key
fgets(buffer, 5000, fp);
len = strlen(buffer) + 1;
node->key = (char*) malloc(sizeof(char)*len);
strcpy(node->key, buffer);
//datasize
fgets(buffer, 5000, fp);
fscanf(fp, "%d", &(node->datasize));
fread(buffer, node->datasize, sizeof(char), fp);
//data
node->data = malloc(sizeof(char)*node->datasize);
memcpy(node->data, buffer, sizeof(char)*node->datasize);
}