#include <stdio.h> #include <stdlib.h> #include <string.h> // 图书结构体定义 typedef struct BookNode { char title[100]; // 书名 float price; // 价格 struct BookNode* next; // 下一节点指针 } BookNode; // 全局头结点 BookNode* head = NULL; // 创建新节点并初始化 BookNode* createNewBook(const char* title, float price) { BookNode* newNode = (BookNode*)malloc(sizeof(BookNode)); strncpy(newNode->title, title, sizeof(newNode->title)-1); newNode->price = price; newNode->next = NULL; return newNode; } // 增加一本书到链表开头 void addBook() { char title[100]; float price; printf("输入书名: "); scanf("%99s", title); // 输入时注意缓冲区溢出风险 printf("输入价格: "); scanf("%f", &price); BookNode* newBook = createNewBook(title, price); if (head == NULL) { // 空链表情况 head = newBook; } else { // 否则添加到列表前面 newBook->next = head; head = newBook; } printf("成功添加书籍!\n"); } // 删除指定标题的书籍 void removeBook(const char* title) { if (head == NULL) { printf("链表为空无法删除.\n"); return; } if (!strcmp(head->title, title)) { // 若首节点即为目标项,则直接移除 BookNode* temp = head; head = head->next; free(temp); printf("删除成功: %s\n", title); return; } // 找到需要删除的前驱节点 BookNode* current = head; while (current->next != NULL && strcmp(current->next->title, title)) current = current->next; if (current->next == NULL) { printf("未找到该书 (%s).\n", title); return; } BookNode* toRemove = current->next; current->next = toRemove->next; free(toRemove); printf("删除成功: %s\n", title); } // 显示所有书籍 void listBooks() { BookNode* temp = head; if (temp == NULL){ printf("无任何书籍记录.\n"); return; } printf("---------------------------\n"); while (temp != NULL) { printf("书名: %-20s | 价格: %.2f\n", temp->title, temp->price); temp = temp->next; } printf("---------------------------\n"); } // 主函数入口 int main(){ int choice; char inputTitle[100]; while(1){ // 循环菜单供用户选择操作 printf("\n=== 图书管理系统 ===\n"); printf("1. 添加书籍\n"); printf("2. 列出所有书籍\n"); printf("3. 删除书籍\n"); printf("4. 结束程序\n"); printf("请选择: "); scanf("%d",&choice); switch(choice){ case 1: addBook(); break; case 2: listBooks(); break; case 3: printf("请输入要删除的书名:"); scanf("%99s",inputTitle); removeBook(inputTitle); break; case 4: exit(EXIT_SUCCESS); // 正常结束程序 default: printf("错误选项,请重新选择.\n"); } } return 0; }
时间: 2025-06-25 20:16:49 AIGC 浏览: 23
这个代码实现了一个简单的图书管理系统的功能,利用了单向链表存储书籍信息。以下是详细的解释:
### 1. **头文件引入**
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
```
这三个头文件分别用于标准输入输出、动态内存分配以及字符串处理。
---
### 2. **数据结构定义**
#### 定义`BookNode`结构体:
```c
typedef struct BookNode {
char title[100]; // 存储书名,最大长度为99字符 + '\0'
float price; // 保存书的价格
struct BookNode* next;// 链接下一本书的指针,默认指向NULL
} BookNode;
```
这是一个典型的链表节点设计。每个节点包含三部分内容:
- `char title[100]`: 字符数组形式存放书名。
- `float price`: 浮点数表示书价。
- `struct BookNode *next`: 指向下一本图书的信息地址(即下一个节点)。如果当前节点是最后一个节点,则其值为NULL。
此外还通过`typedef`简化了后续引用名称书写方便性。
全局变量声明了链表头部:
```c
BookNode* head = NULL; // 表示目前没有任何书籍入库的状态
```
---
### 3. **核心函数解析**
#### 函数`createNewBook()` - 动态创建并初始化新的书籍节点
此函数负责申请一块堆上空间来储存新录入的一本图书的具体详情,并将之返回给调用者。
```c
BookNode* createNewBook(const char* title, float price)
{
BookNode* newNode = (BookNode*)malloc(sizeof(BookNode));
strncpy(newNode->title,title,sizeof(newNode->title)-1); //拷贝不超过99字节长的数据到字段内避免越界访问引发崩溃等问题发生;最后一位留作终止标志'\0'.
newNode->price=price; //赋值售价金额进去成员变量里去
newNode->next=NULL; //初始状态设置链接域为空表明暂时没有其他关联项目存在于是就结束整个过程啦~
return newNode ;
}
```
---
#### 函数`addBook()` - 用户交互新增一本书籍至数据库前端位置处
首先提示使用者填写必要的基本信息包括但不限于标题内容及定价情况等方面的内容;
然后依据所得结果构建对应的实体对象实例化操作完成后将其插入到现有序列最前面作为最新的条目显示出来而已咯。
```c
void addBook()
{
char title[100];
float price;
printf("请输入书名:");
scanf("%99s", title);
printf("请输入价格:");
scanf("%f", &price);
BookNode *newBook=createNewBook(title,price);
if(!head)//当原来不存在任何元素的时候直接让根节点指向刚生成的那个就好啦!
head=newBook;
else//反之则需调整顺序保证符合要求即可完成任务哟~
{
newBook->next=head;
head=newBook;
}
printf("成功添加书籍!\n");
}
```
---
#### 函数`removeBook()` – 根据提供的书名查找匹配项并予以销毁释放资源回收动作执行完毕为止结束流程正常退出即可哈~
若目标存在于首位可以直接断开连接同时别忘了清理不再使用的那块区域防止泄露现象产生影响系统性能表现等不良后果哦亲们记住了吗😊
对于非起始情形下的场景来说就需要遍历直至定位正确的前置单元然后再实施相应的拆解工作步骤依次进行下去直到全部处理妥当方才罢休啊朋友们💪!
```c
void removeBook(char const *title)
{
if(NULL==head)
{printf("空表无法删减");return;}
else if(0==strcmp(head->title,title))
{/*如果是第一个节点就要特别对待一下*/
BookNode*pTemp=head;pHead=pHead->pNext;
free(pTemp);
printf("已移除:%s\n",title);}
/*如果不是首元那么继续往下找寻合适的机会动手吧😄*/
else{for(BookNode*pCur=head;pCur&&pCur->pNext;pCur=pCur->pNext)
{if(0!=strncmp((pCur->pNext)->m_szName,title,strlen(m_szName)))continue;
/*找到了待处置的目标可以行动起来啰😁 */
BookNode*todelete=(pCur->pNext);
pCur->pNext=todelete->pNext;
free(todelete);
printf("已完成对%s的操作!",title);
break;}}
if(NULL==findBookByName(title))puts("未发现对应记录!");
}
```
---
### §相关问题§ :
1. 在该程序中如何修改才能支持按任意键退出而不是只限于数字"4"?
2. 能否优化`addBook`使得每次加入的新书籍总是追加到最后而不是覆盖原有排列次序?
3. 如果想增加查询某个特定名字是否存在这样的功能应当怎样补充完整呢?
阅读全文
相关推荐




















