我做了一个基于哈希表的身份证查询系统,运行程序想把输入的信息写入文件中
void Save(IDLnode*& L)
{
FILE* fp = fopen("D:\\IDcardSearchSystem.txt", "w");//打开文件
if (fp == NULL)
{
perror("打开文件失败\n");
system("pause");
system("cls");
return;
}
IDLnode* p = L;
while (p != NULL)
{
fwrite(&p, sizeof(IDLnode),1, fp);
p = p->next;
}
fclose(fp); //关闭文件
printf("保存成功!\n");
}
void Load(IDLnode*& L)
{
FILE* fp = fopen("D:\\IDcardSearchSystem.txt", "r");//打开文件
if (fp == NULL)
{
perror("\n打开文件失败.\n");
return;
}
IDLnode p;
while (fread(&p, sizeof(IDLnode),1, fp))
{
//创建新节点
IDLnode* pNewNode = (IDLnode*)malloc(sizeof(IDLnode));
pNewNode->next = NULL;
//memcpy(pNewNode, &stu, sizeof(IDLnode));
if (pNewNode != NULL)
{
strcpy(pNewNode->ID, p.ID);
strcpy(pNewNode->Name, p.Name);
strcpy(pNewNode->Address, p.Address);
pNewNode->next = L;
L = pNewNode;
}
}
fclose(fp);
printf("\n读取成功!\n");
system("pause");
system("cls");
}
但是当我重新运行程序后,读取信息并将读取的信息打印在屏幕上发现是乱码,而非我之前填入的信息,这是为什么啊
以下是部分代码
#define HashTableLength 50 //哈希表长度
#define IdLength 20 //身份证号长度
#define Prime 47 //质数
#define NameLength 30
#define AddressLength 50
//身份证单链表
typedef struct IDLnode
{
char ID[IdLength]; //身份证号
char Name[NameLength]; //姓名
char Address[AddressLength]; //地址
struct IDLnode* next;
}IDLnode;
//身份证号哈希表
typedef struct IDHashTable
{
char HI_ID[IdLength];
char HI_Name[NameLength];
char HI_Address[AddressLength];
int state;
}IDHashTable;
//姓名哈希表
typedef struct NameHashTable
{
char HN_ID[IdLength];
char HN_Name[NameLength];
char HN_Address[AddressLength];
int state;
}NameHashTable;
bool Insert(IDLnode*& L, IDHashTable*& IH, NameHashTable*& NH, const char* id, const char* name, const char* address)
{
//头插添加进链表
IDLnode* p = (IDLnode*)malloc(sizeof(IDLnode));
if (p != NULL)
{
strcpy(p->ID, id);
strcpy(p->Name, name);
strcpy(p->Address, address);
p->next = L;//->next;
L = p;
}
const char temp[1] = { '\0' };
//用哈希函数抽象出关键字放入哈希表中
int namekey = HashName(name); //获取关键字
int idkey = HashID(id);
//放入身份证号哈希表中
while (IH[idkey].state == 1 && strcmp(IH[idkey].HI_ID, temp) != 0) //线性探测再散列法,用state判断是否冲突,当state=1为冲突,向后存放关键字
idkey++;
strcpy(IH[idkey].HI_ID, id);
strcpy(IH[idkey].HI_Name, name);
strcpy(IH[idkey].HI_Address, address);
IH[idkey].state = 1;
//放入姓名哈希表中
while (NH[namekey].state == 1 && strcmp(NH[namekey].HN_ID, temp) != 0)
namekey++;
strcpy(NH[namekey].HN_ID, id);
strcpy(NH[namekey].HN_Name, name);
strcpy(NH[namekey].HN_Address, address);
NH[namekey].state = 1;
return true;
}
在保存和加载时使用的是二进制文件,这是因为在 Save 函数中使用了 fwrite,而在 Load 函数中使用了 fread。
在这种情况下,应该将文件以二进制格式打开,而不是使用文本模式。在 Save 函数中,应使用 "wb" 模式打开文件,而在 Load 函数中,应使用 "rb" 模式打开文件。
在 Load 函数中,需要将新节点的 next 指针设置为 NULL,否则将在读取新节点时可能遇到问题。
如果希望保留原来的信息,并在文件的末尾添加新的信息,则应在 Save 函数中使用 "a" 模式打开文件。
在使用二进制文件时,请确保结构体中没有任何动态分配的内存,因为这可能会导致问题。例如,如果结构体中有指针字段,则可能需要编写自己的读写函数来处理这些字段。
根据结构体来写入文件,其实写入的是二进制数据流,而记事本编码不支持二进制,所以会导致乱码,在读取的时候用相对应的fread能准确地读出写入的内容,若不想在记事本上显示乱码数据。可以考虑使用fprintf和fscanf。
你用的是哪个编译的
你试试这个
将txt文本编码格式改成ANSI:打开记事本->文件->另存为->更改编码格式为ANSI->保存。