用c语言代码做班级通讯查询系统,基本要求,数据为本班全体同学信息,存储方式采用哈希表,可增、删、改信息,并可按电话号码和姓名查找,然后可以将增删改的学生信息写入文件中,每次查询前读取文件
时间: 2024-03-16 11:47:24 浏览: 16
好的,这是一个比较全面的需求,需要涉及到哈希表、文件读写、字符串处理等知识点。下面是一个简单的实现方案,供参考:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NAME_LEN 20
#define MAX_PHONE_LEN 11
#define TABLE_SIZE 100
// 定义学生结构体
typedef struct {
char name[MAX_NAME_LEN];
char phone[MAX_PHONE_LEN];
} Student;
// 定义哈希表节点结构体
typedef struct {
char key[MAX_PHONE_LEN];
Student value;
} Node;
// 定义哈希表结构体
typedef struct {
Node nodes[TABLE_SIZE];
int size;
} HashTable;
// 哈希函数,将电话号码转化为哈希值
int hash(char* phone) {
int sum = 0;
for (int i = 0; i < strlen(phone); i++) {
sum += phone[i];
}
return sum % TABLE_SIZE;
}
// 初始化哈希表
void initHashTable(HashTable* table) {
table->size = 0;
memset(table->nodes, 0, sizeof(Node) * TABLE_SIZE);
}
// 插入节点
void insertNode(HashTable* table, char* phone, Student* student) {
if (table->size >= TABLE_SIZE) {
printf("Error: hash table is full!\n");
return;
}
int index = hash(phone);
while (table->nodes[index].key[0] != '\0') {
index = (index + 1) % TABLE_SIZE;
}
strcpy(table->nodes[index].key, phone);
table->nodes[index].value = *student;
table->size++;
}
// 删除节点
void deleteNode(HashTable* table, char* phone) {
int index = hash(phone);
while (table->nodes[index].key[0] != '\0') {
if (strcmp(table->nodes[index].key, phone) == 0) {
memset(table->nodes[index].key, 0, sizeof(table->nodes[index].key));
memset(&table->nodes[index].value, 0, sizeof(Student));
table->size--;
return;
}
index = (index + 1) % TABLE_SIZE;
}
printf("Error: student not found!\n");
}
// 查找节点
Node* findNode(HashTable* table, char* phone) {
int index = hash(phone);
while (table->nodes[index].key[0] != '\0') {
if (strcmp(table->nodes[index].key, phone) == 0) {
return &table->nodes[index];
}
index = (index + 1) % TABLE_SIZE;
}
return NULL;
}
// 修改节点
void modifyNode(HashTable* table, char* phone, Student* student) {
Node* node = findNode(table, phone);
if (node != NULL) {
node->value = *student;
} else {
printf("Error: student not found!\n");
}
}
// 打印学生信息
void printStudent(Student* student) {
printf("name: %s, phone: %s\n", student->name, student->phone);
}
// 打印哈希表
void printHashTable(HashTable* table) {
for (int i = 0; i < TABLE_SIZE; i++) {
if (table->nodes[i].key[0] != '\0') {
printf("index: %d, key: %s, value: ", i, table->nodes[i].key);
printStudent(&table->nodes[i].value);
}
}
}
// 保存学生信息到文件
void saveToFile(HashTable* table, char* filename) {
FILE* fp = fopen(filename, "w");
if (fp == NULL) {
printf("Error: cannot open file %s!\n", filename);
return;
}
for (int i = 0; i < TABLE_SIZE; i++) {
if (table->nodes[i].key[0] != '\0') {
fprintf(fp, "%s %s\n", table->nodes[i].key, table->nodes[i].value.name);
}
}
fclose(fp);
}
// 从文件读取学生信息
void loadFromFile(HashTable* table, char* filename) {
FILE* fp = fopen(filename, "r");
if (fp == NULL) {
printf("Error: cannot open file %s!\n", filename);
return;
}
char phone[MAX_PHONE_LEN];
char name[MAX_NAME_LEN];
while (fscanf(fp, "%s %s", phone, name) != EOF) {
Student student;
strcpy(student.name, name);
strcpy(student.phone, phone);
insertNode(table, phone, &student);
}
fclose(fp);
}
int main() {
HashTable table;
initHashTable(&table);
loadFromFile(&table, "students.txt");
int choice;
while (1) {
printf("1. add student\n");
printf("2. delete student\n");
printf("3. modify student\n");
printf("4. search by phone\n");
printf("5. search by name\n");
printf("6. print all students\n");
printf("7. save to file\n");
printf("8. exit\n");
printf("please enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1: {
Student student;
printf("please enter the name: ");
scanf("%s", student.name);
printf("please enter the phone: ");
scanf("%s", student.phone);
insertNode(&table, student.phone, &student);
break;
}
case 2: {
char phone[MAX_PHONE_LEN];
printf("please enter the phone: ");
scanf("%s", phone);
deleteNode(&table, phone);
break;
}
case 3: {
char phone[MAX_PHONE_LEN];
printf("please enter the phone: ");
scanf("%s", phone);
Student student;
printf("please enter the new name: ");
scanf("%s", student.name);
printf("please enter the new phone: ");
scanf("%s", student.phone);
modifyNode(&table, phone, &student);
break;
}
case 4: {
char phone[MAX_PHONE_LEN];
printf("please enter the phone: ");
scanf("%s", phone);
Node* node = findNode(&table, phone);
if (node != NULL) {
printf("student found: ");
printStudent(&node->value);
} else {
printf("student not found!\n");
}
break;
}
case 5: {
char name[MAX_NAME_LEN];
printf("please enter the name: ");
scanf("%s", name);
int found = 0;
for (int i = 0; i < TABLE_SIZE; i++) {
if (table.nodes[i].key[0] != '\0' && strcmp(table.nodes[i].value.name, name) == 0) {
printf("student found: ");
printStudent(&table.nodes[i].value);
found = 1;
}
}
if (!found) {
printf("student not found!\n");
}
break;
}
case 6: {
printHashTable(&table);
break;
}
case 7: {
saveToFile(&table, "students.txt");
break;
}
case 8: {
return 0;
}
default: {
printf("Error: invalid choice!\n");
}
}
}
return 0;
}
```
这个程序使用哈希表来存储学生信息,每个节点包含一个电话号码作为键,以及一个学生结构体作为值。哈希函数将电话号码转化为哈希值,然后使用线性探测法解决哈希冲突,即如果插入的位置已经有节点了,就往后找第一个空位置。
程序提供了增删改查等基本操作,以及将学生信息保存到文件和从文件读取学生信息的功能。在每次查询前,程序会从文件中读取学生信息,保证数据的一致性。
注意,这个程序只是一个简单的实现方案,还有很多细节可以优化和完善,例如对用户输入的合法性进行验证,对哈希表容量进行动态调整等。