c - C语言将二进制文件读入HashTable

标签 c io binary hashtable read-write

因此,我正在创建一个密码保管库,并且需要能够将哈希表保存到二进制文件,并在登录时将二进制文件中的相同内容读回到程序哈希表中

我已经用 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);

}

我知道段错误不是来自 insertData 函数,因为我已经测试过它并且知道它可以正常工作。我对我做错的事情的最佳猜测是我的 fwrite 条件不正确,或者当我读取数据时我在某处错误地管理内存。

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;

感谢您的反馈!!

最佳答案

首先,fwrite()/fread()的参数1是void *,而不是**void ****。

第二,你不能使用fwrite()/fread()来保存/恢复你的数据,因为Node的成员{key, data}是指针,指示额外的数据内存数据,但是使用 fwrite()/fread() 只是操作指针 {char *, void *, Node *},而不是额外的数据。

对于 key ,有一个示例:

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() 。

第三,我的一个 HashMap 实现可能可以帮助你: https://github.com/foreverpersist/hashmap

关于c - C语言将二进制文件读入HashTable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50960037/

相关文章:

c - 尝试导入头文件并使用它时 C 中的段错误

java - 使用 java.io.File 在 Eclipse 中创建目录

haskell - 在 Haskell 中检索文件大小的 hFileSize 更快替代方案?

c - 为什么我们将 (temp>>11) 乘以 2 来找到此代码中的第二个

java - 尝试将二进制转换为十六进制时不一致地获得 NumberFormatException

c++ - 在 GCC/G++ 编译器中使用 -pedantic 的目的是什么?

使用共享库交叉编译应用程序

java - 网络/数据库作业的足够线程数

c - 直接从 C 中的(共享)内存执行二进制/elf 文件

C 为什么可以声明具有可变大小(但固定列)的二维数组的函数