还有很多bug 的 图书管理系统
    看着视频教学 写的 添加了文字颜色等
    能力有限 就这个小东西都还没有吃透 ,
    还有很多bug 比如输入错误会 一直循环 等等
    学c语言 指针结构体 后面这部分就学了皮毛还是理解太差了 ,后面会改进

    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include <string.h>
    4. #include <stdbool.h>
    5. #include <Windows.h>
    6. typedef struct Node { //书的结构体 节点
    7. struct Node * Upper; //Upper 上 指向上的指针
    8. struct Node * Lower; //Lower 下 指向下的指针
    9. char BookName[100]; //定义书名
    10. float Bookprice; //定义书价
    11. int BookNumber; //定义书号
    12. };
    13. int nNodeCount = 0; //节点总数的计数
    14. struct Node* nDHeaderNode = NULL;
    15. //增加函数
    16. struct Node * AppendNode(struct Node * CurrentNode, char * BookName, int BookNumber, float Bookprice);
    17. //查询函数
    18. void QueryNode(struct Node* HeaderNode, char* BookName);
    19. //修改函数
    20. void ModifyNode(struct Node* HeaderNode, char* BookName, float Bookprice);
    21. //删除的函数
    22. void DeleteNode(struct Node* HeaderNode, char* BookName);
    23. //颜色
    24. void color(short x);
    25. int main()
    26. {
    27. while (true)
    28. {
    29. color(14);
    30. int ReadFlag = 0;
    31. char szBookName[100]; //书名
    32. float fBookprice; // 书价
    33. int nBookNumber; //书号
    34. float fNewBookprice; //新的书价
    35. printf("-------------------------------请输入您需要的功能---------------------------------\n");
    36. printf(" 1: 添加书籍信息 \n");
    37. printf(" 2: 查询书籍信息 \n");
    38. printf(" 3: 修改书籍信息 \n");
    39. printf(" 4: 删除书籍信息 \n");
    40. scanf("%d", &ReadFlag);
    41. switch (ReadFlag)
    42. {
    43. system("cls");
    44. case 1:
    45. memset(szBookName, 0, 50);
    46. printf(" 请输入书名:\n");
    47. scanf("%s", szBookName);
    48. printf(" 请输入定价:\n");
    49. scanf("%f", &fBookprice);
    50. printf(" 请输出书号:\n");
    51. scanf("%d", &nBookNumber);
    52. //新增的函数
    53. nDHeaderNode = AppendNode(nDHeaderNode, szBookName, nBookNumber, fBookprice);
    54. break;
    55. case 2:
    56. memset(szBookName, 0, 50);
    57. printf(" 请输出书名:\n");
    58. scanf("%s", szBookName);
    59. //code 查询的函数
    60. QueryNode(nDHeaderNode,szBookName);
    61. break;
    62. case 3:
    63. memset(szBookName, 0, 50);
    64. printf(" 请输入书名:\n");
    65. scanf("%s", szBookName);
    66. printf(" 请输入新定价:\n");
    67. scanf("%f", &fNewBookprice);
    68. //code 修改的函数
    69. ModifyNode(nDHeaderNode, szBookName, fNewBookprice);
    70. break;
    71. case 4:
    72. memset(szBookName, 0, 50);
    73. printf(" 请输入书名:\n");
    74. scanf("%s", szBookName);
    75. //code 删除的函数
    76. DeleteNode(nDHeaderNode, szBookName);
    77. break;
    78. default:
    79. break;
    80. }
    81. }
    82. return 0;
    83. }
    84. struct Node * AppendNode(struct Node * CurrentNode, char * BookName, int BookNumber, float Bookprice) //Current 当前节点
    85. {
    86. struct Node * pNewNode = NULL; //pNewNode 新的节点
    87. struct Node * pTempNode = NULL; // pTempNode 临时节点
    88. struct Node* pHeadNode = CurrentNode; //pHeadNode 头节点
    89. pNewNode = (struct Node*)malloc(sizeof(struct Node)); //申请 一个节点(Node)那么大的内存 malloc 申请内存
    90. if (pNewNode == NULL)
    91. {
    92. printf("Failed to request memory!\n"); //申请内存失败
    93. return pNewNode;
    94. }
    95. if (CurrentNode == NULL) // 等于NULL 就是空链表
    96. {
    97. CurrentNode = pNewNode; // 开辟出内存空间的新节点 ,赋值给当前节点
    98. CurrentNode->Upper = NULL; //当前节点的上下节点 都置为空 前后都没有值
    99. CurrentNode->Lower = NULL;
    100. }
    101. else
    102. {
    103. while(pHeadNode->Lower!=NULL) //头节点 指向下一个节点 不等于 NULL
    104. {
    105. pTempNode = pHeadNode;
    106. pHeadNode = pHeadNode->Lower;
    107. }
    108. pHeadNode->Lower = pNewNode;
    109. pHeadNode->Upper = pTempNode;
    110. }
    111. strcpy(pNewNode->BookName, BookName); //拷贝书名
    112. pNewNode->Bookprice = Bookprice; //新的节点的定价等于参数的定价
    113. pNewNode->BookNumber = BookNumber; //新的节点的书号等于参数的书号
    114. pNewNode->Lower = NULL; //新节点的下一个节点置空
    115. nNodeCount++; //计数器自增
    116. return CurrentNode; //返回当前节点
    117. }
    118. void QueryNode(struct Node* HeaderNode, char* BookName)
    119. {
    120. if (HeaderNode == NULL)
    121. {
    122. printf(" error:查询失败,没有该书籍\n");
    123. return;
    124. }
    125. for (size_t i = 0; i < nNodeCount; i++) //for循环遍历
    126. {
    127. if (strcmp(HeaderNode->BookName, BookName) == 0) //strcmp = 0 才是 正确
    128. {
    129. printf(" 图书书名:%s\n", HeaderNode->BookName);
    130. printf(" 图书定价:%f\n", HeaderNode->Bookprice);
    131. printf(" 图书书号:%d\n", HeaderNode->BookNumber);
    132. return;
    133. }
    134. HeaderNode = HeaderNode->Lower;
    135. }
    136. printf("Query Node Failed\n");
    137. }
    138. void ModifyNode(struct Node * HeaderNode, char* BookName, float Bookprice)
    139. {
    140. if (HeaderNode == NULL)
    141. {
    142. printf(" error:查询失败没有书籍\n");
    143. return;
    144. }
    145. if (strcmp(HeaderNode->BookName,BookName)== 0)
    146. {
    147. HeaderNode->Bookprice = Bookprice;
    148. printf("Modify Success !\n");
    149. return;
    150. }
    151. while (HeaderNode->Lower != NULL)
    152. {
    153. HeaderNode = HeaderNode->Lower;
    154. if (strcmp(HeaderNode->BookName, BookName) == 0)
    155. {
    156. HeaderNode->Bookprice = Bookprice;
    157. printf("Modify Success !\n");
    158. return;
    159. }
    160. }
    161. printf("ModifyNode failed!");
    162. return;
    163. }
    164. void DeleteNode( struct Node* HeaderNode, char* BookName)
    165. {
    166. struct Node * pNode = NULL; //定义一个指针临时节点
    167. pNode = HeaderNode; //临时节点指向头节点
    168. for (size_t i = 0; i < nNodeCount; i++) //
    169. {
    170. if (strcmp(pNode->BookName,BookName)==0) // 比较名字是否一样 ,一样等于 0
    171. {
    172. if (pNode == HeaderNode) // 相等删除的就是头节点
    173. {
    174. pNode = HeaderNode->Lower; // 头节点指向下一个节点
    175. free(HeaderNode); //释放内存空间函数free 调用形式: free(void *ptr);
    176. nDHeaderNode = pNode; //全局头节点 指向 pNode临时节点
    177. HeaderNode = nDHeaderNode;
    178. nNodeCount--; //总数减一 因为删除了一个节点所以减一
    179. return;
    180. }
    181. if (pNode->Lower == NULL)
    182. {
    183. pNode->Upper->Lower = NULL; //当前的临时节点 指向上一个节点 指向下一个节点
    184. free(pNode); //上的下一个节点,指向的就是自己,把自己free掉
    185. nNodeCount--;
    186. printf("Delete Success!\n"); //删除成功
    187. return;
    188. }
    189. pNode->Upper->Lower = pNode->Lower; //当前节点指向上一个节点-指向下一个节点 = 当前节点 指向下一个节点
    190. pNode->Lower->Upper = pNode->Upper;
    191. free(pNode); //把当前节点空出来了 就free掉
    192. nNodeCount--;
    193. printf("Delete Success!\n");
    194. return;
    195. }
    196. pNode = pNode->Lower;
    197. }
    198. }
    199. void color(short x)
    200. {
    201. if (x >= 0 && x <= 15)
    202. {
    203. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);
    204. }
    205. else
    206. {
    207. SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);
    208. }
    209. }