C语言任务描述 本关任务:定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建,然后将读入的图书逆序存储,逐行输出逆序存储后每本图书的信息。 编程要求 输入 输入n+1行,第一行是图书数目n,后n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格。其中书号和书名为字符串类型,价格为浮点数类型。 输出 总计n行,第i行是原有图书表中第n-i+1行的图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔。其中价格输出保留两位小数。 测试说明 平台会对你编写的代码进行测试: 测试输入: 8 9787302257646 Data-Structure 35.00 9787302164340 Operating-System 50.00 9787302219972 Software-Engineer 32.00 9787302203513 Database-Principles 36.00 9787810827430 Discrete-Mathematics 36.00 9787302257800 Data-Structure 62.00 9787811234923 Compiler-Principles 62.00 9787822234110 The-C-Programming-Language 38.00 预期输出: 9787822234110 The-C-Programming-Language 38.00 9787811234923 Compiler-Principles 62.00 9787302257800 Data-Structure 62.00 9787810827430 Discrete-Mathematics 36.00 9787302203513 Database-Principles 36.00 9787302219972 Software-Engineer 32.00 9787302164340 Operating-System 50.00 9787302257646 Data-Structure 35.00
时间: 2025-07-11 16:49:25 浏览: 6
<think>好的,我需要帮助用户实现一个包含图书信息的链表,并完成逆序存储及输出的功能。首先,我需要明确用户的需求:他们希望用C语言创建一个链表结构来存储图书信息,然后逆序存储这些数据并输出。图书信息可能包括书名、作者、价格等字段,用户提到的浮点数和字符串处理应该对应价格和字符串类型的字段。
首先,我得确定数据结构。用户提到了链表操作,所以应该定义一个结构体来表示每个图书节点。结构体应该包含书名(字符串)、作者(字符串)、价格(浮点数)以及指向下一个节点的指针。例如:
typedef struct BookNode {
char title[100];
char author[50];
float price;
struct BookNode* next;
} BookNode;
接下来是创建链表。用户需要输入多本图书的信息,直到满足某个终止条件(比如输入特定字符)。这里可能需要使用循环来不断接收输入,并动态分配内存创建新节点。需要注意的是,字符串的输入要避免缓冲区溢出,所以应该使用安全的函数如fgets,或者限制scanf的读取长度。例如:
BookNode* createLinkedList() {
BookNode* head = NULL;
BookNode* tail = NULL;
char choice;
do {
BookNode* newBook = (BookNode*)malloc(sizeof(BookNode));
printf("输入书名: ");
scanf("%99s", newBook->title); // 防止溢出
printf("输入作者: ");
scanf("%49s", newBook->author);
printf("输入价格: ");
scanf("%f", &newBook->price);
newBook->next = NULL;
// 将新节点添加到链表
if (head == NULL) {
head = newBook;
tail = newBook;
} else {
tail->next = newBook;
tail = newBook;
}
printf("继续输入?(y/n): ");
scanf(" %c", &choice); // 注意空格,跳过换行符
} while (choice == 'y' || choice == 'Y');
return head;
}
然后是逆序存储。逆序链表通常有两种方法:迭代法和递归法。迭代法更高效,适用于长链表。基本思路是遍历原链表,逐个将节点插入到新链表的头部。例如:
BookNode* reverseLinkedList(BookNode* head) {
BookNode* prev = NULL;
BookNode* current = head;
BookNode* next = NULL;
while (current != NULL) {
next = current->next;
current->next = prev;
prev = current;
current = next;
}
return prev;
}
最后是输出链表。需要遍历链表,打印每个节点的信息。对于逆序后的链表,同样遍历即可:
void printLinkedList(BookNode* head) {
BookNode* current = head;
while (current != NULL) {
printf("书名: %s\n作者: %s\n价格: %.2f\n\n", current->title, current->author, current->price);
current = current->next;
}
}
需要注意内存管理,使用完毕后应释放链表占用的内存,防止内存泄漏。此外,用户提到浮点数处理,要确保正确读取和输出,使用%.2f来保留两位小数。字符串处理方面,使用安全的输入函数,避免溢出。
可能的问题:用户输入时,如果使用scanf读取字符串,遇到空格会截断。比如书名中有空格,会导致问题。这时应该使用fgets或者调整scanf的格式,如%99[^\n]来读取整行。但需要注意清除输入缓冲区中的换行符,避免影响后续输入。
例如,修改读取书名的部分:
printf("输入书名: ");
scanf(" %99[^\n]", newBook->title); // 前面的空格跳过空白字符,读取直到换行符
或者使用fgets:
fgets(newBook->title, 100, stdin);
// 去除换行符
size_t len = strlen(newBook->title);
if (len > 0 && newBook->title[len-1] == '\n') {
newBook->title[len-1] = '\0';
}
这可能更安全,但需要注意fgets会读取换行符,需要处理。
在编写完整代码时,要包含必要的头文件,如stdio.h、stdlib.h、string.h。主函数中调用创建、逆序、输出链表的函数,并最后释放内存。
测试部分需要考虑各种情况,如空链表、单节点链表、多节点链表,确保逆序正确。同时处理用户输入中的异常情况,比如输入非数值字符时价格的处理,可能需要添加错误检查。
总结步骤:
1. 定义结构体
2. 创建链表函数
3. 逆序链表函数
4. 输出链表函数
5. 主函数中整合流程
6. 内存释放
7. 测试与调试
用户可能还需要示例代码,所以需要将上述各部分组合成一个完整的程序,并确保代码符合C语言标准,可编译运行。</think>以下是C语言实现图书信息链表的创建、逆序存储及输出的完整示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义图书信息结构体
typedef struct BookNode {
char title[100];
char author[50];
float price;
struct BookNode* next;
} BookNode;
// 创建链表函数
BookNode* createLinkedList() {
BookNode* head = NULL;
BookNode* tail = NULL;
char choice;
do {
BookNode* newBook = (BookNode*)malloc(sizeof(BookNode));
// 输入处理
printf("请输入书名:");
scanf(" %99[^\n]", newBook->title);
getchar(); // 清除缓冲区
printf("请输入作者:");
scanf(" %49[^\n]", newBook->author);
getchar();
printf("请输入价格:");
while(scanf("%f", &newBook->price) != 1) {
printf("输入错误,请重新输入价格:");
while(getchar() != '\n'); // 清空输入缓冲区
}
getchar();
newBook->next = NULL;
// 链表连接
if (head == NULL) {
head = tail = newBook;
} else {
tail->next = newBook;
tail = newBook;
}
printf("\n继续添加图书?(y/n): ");
scanf(" %c", &choice);
getchar();
} while(choice == 'y' || choice == 'Y');
return head;
}
// 逆序链表函数(迭代法)
BookNode* reverseLinkedList(BookNode* head) {
BookNode *prev = NULL;
BookNode *current = head;
BookNode *next = NULL;
while (current != NULL) {
next = current->next;
current->next = prev;
prev = current;
current = next;
}
return prev;
}
// 输出链表函数
void printLinkedList(BookNode* head) {
BookNode* current = head;
int count = 1;
printf("\n图书信息列表:\n");
while (current != NULL) {
printf("第%d本:\n", count++);
printf("书名:%s\n", current->title);
printf("作者:%s\n", current->author);
printf("价格:%.2f\n\n", current->price);
current = current->next;
}
}
// 释放内存函数
void freeLinkedList(BookNode* head) {
BookNode* tmp;
while (head != NULL) {
tmp = head;
head = head->next;
free(tmp);
}
}
int main() {
BookNode* head = NULL;
// 创建链表
head = createLinkedList();
// 原始顺序输出
printf("\n原始顺序:");
printLinkedList(head);
// 逆序处理
head = reverseLinkedList(head);
// 逆序后输出
printf("\n逆序后结果:");
printLinkedList(head);
// 释放内存
freeLinkedList(head);
return 0;
}
```
### 代码说明:
1. **数据结构定义**
使用`BookNode`结构体存储图书信息,包含:
- 书名(字符串)
- 作者(字符串)
- 价格(浮点数)
- 指向下一个节点的指针
2. **输入处理优化**
- 使用`scanf(" %99[^\n]", ...)`处理含空格的字符串输入[^1]
- 价格输入增加错误检查
- 使用`getchar()`清除输入缓冲区残留字符
3. **链表操作**
- **创建链表**:动态内存分配,尾部插入法
- **逆序操作**:使用三指针迭代法实现$O(n)$时间复杂度
- **输出功能**:格式化输出浮点数(保留两位小数)
4. **内存管理**
包含专门的`freeLinkedList`函数防止内存泄漏
阅读全文
相关推荐













