C语言中如何实现从标准输入一行读取多组AVL树节点数据
解决AVL树节点批量输入的问题
我明白你的需求啦——现在你的代码只能一行处理一个节点,但你想一次性输入所有(key, value)格式的节点,按回车后一次性解析完,对吧?咱们来一步步搞定这个问题。
首先先揪出原代码里的两个小问题:
- 换行判断错误:你写的
*str == "\n"是把单个字符和字符串常量比较,这在C里是不成立的,应该改成判断单个换行符str[0] == '\n',还要考虑空字符串的情况。 - 单次
sscanf只能处理一个节点,没法遍历整行里的多个节点。
接下来是核心解决方案:读取完整一行后,循环遍历字符串,逐个解析每个节点。具体怎么做呢?
关键思路
- 用
fgets读取整行输入(不管一行里塞了多少个节点)。 - 用一个指针遍历这行字符串,每次用
sscanf匹配( %d, %d )的格式,同时用%n记录本次匹配消耗的字符数,这样指针就能精准跳到下一个节点的位置。 - 循环解析直到无法匹配到有效节点为止,处理完当前行后继续读下一行,直到遇到空行(用户直接按回车)就停止输入。
修改后的完整代码示例
#include <stdio.h> #include <stdlib.h> #include <string.h> // 这里可以保留你的AVL树插入函数声明 // void InsertNode(AVLTree *tree, int key, int value); int main() { char str[1024]; int key, value; // 读取每一行输入,直到EOF或者空行 while (fgets(str, sizeof(str), stdin) != NULL) { // 处理空行:如果行首是换行符或者空字符串,停止输入 if (str[0] == '\n' || str[0] == '\0') { break; } // 用指针遍历当前行的所有节点 char *ptr = str; int n; // 记录每次sscanf消耗的字符数 while (sscanf(ptr, "( %d, %d )%n", &key, &value, &n) == 2) { // 成功匹配一个节点,执行插入或打印 // InsertNode(AVLtree, key, value); printf("解析到节点:%d, %d\n", key, value); // 指针跳到下一个节点的起始位置 ptr += n; // 跳过节点之间的空格(不管有多少个) while (*ptr == ' ') { ptr++; } } // 检查是否有无效格式的内容 if (*ptr != '\0' && *ptr != '\n') { printf("错误:输入格式无效,剩余内容:%s\n", ptr); exit(1); } } return 0; }
代码细节解释
%n的妙用:sscanf里的%n会把本次调用一共读取的字符数存入变量n,这样我们就能精准移动指针,不会重复解析或者漏掉节点。- 跳过空格:节点之间可能有多个空格,所以每次匹配后要跳过所有空格,确保指针能找到下一个
(的位置。 - 空行终止:当用户直接按回车输入空行时,程序就会停止读取,完全符合你的需求。
测试效果
如果输入:
(7,19) (5,16) (9,13) (3,20)
然后按回车输入空行,程序会输出:
解析到节点:7, 19 解析到节点:5, 16 解析到节点:9, 13 解析到节点:3, 20
这样既支持一次性输入多个节点,也兼容原来每行一个节点的输入方式,灵活性拉满~
内容的提问来源于stack exchange,提问作者leo
相关产品推荐
相关产品推荐

