基于二叉搜索树的代码行计数器开发问题求助
二叉搜索树提取文本标识符问题修复
问题1:编译错误解决
代码里的n -> lineList = {};会触发编译错误,因为C语言不允许直接给数组赋值空大括号(数组属于不可赋值的左值)。替换成memset(n -> lineList, 0, sizeof(n -> lineList));来初始化数组,记得引入<string.h>头文件。
问题2:行号存储逻辑修复
newTree函数原本没接收行号参数,创建新节点时没法存入第一次出现的行号,得加个int lineNumber参数,把行号放到lineList[0]里。- 全局变量
head没初始化,会导致野指针,直接初始化为NULL。 - 主循环里
lineNumber没自增,所有行都被标成了行号1,每次读完一行后要让lineNumber++。 - 结构体里的
struct Word * word;根本没定义,属于冗余代码,直接删掉。 - 提取标识符的内部循环可能越界,要加个
i < len的判断。 - 输出行号时调整格式,加上方括号和逗号分隔,和期望输出一致。
修复后的完整代码
#include <stdio.h> #include <ctype.h> #include <stdlib.h> #include <string.h> struct Node { char * data; int lineList[100]; int counter; struct Node * ltree; struct Node * rtree; }; struct Node * head = NULL; // 初始化避免野指针 struct Node * newTree(char * identifier, int lineNumber) { struct Node * n = malloc(sizeof(struct Node)); n -> data = malloc(strlen(identifier) + 1); memset(n -> lineList, 0, sizeof(n -> lineList)); // 初始化行号数组 n -> counter = 1; strcpy(n -> data, identifier); n -> lineList[0] = lineNumber; // 存入首次出现的行号 n -> ltree = n -> rtree = NULL; return n; } struct Node * insert(struct Node * tree, char * identifier, int lineNumber) { if (tree == NULL) return newTree(identifier, lineNumber); // 传递行号给新节点 int cmp = strcmp(identifier, tree -> data); if (cmp == 0) { // 防数组越界 if (tree->counter >= 100) { printf("Warning: 行号数组已满,无法存储更多行号\n"); return tree; } tree -> lineList[tree -> counter] = lineNumber; tree -> counter++; return tree; } if (cmp < 0) tree -> ltree = insert(tree -> ltree, identifier, lineNumber); else tree -> rtree = insert(tree -> rtree, identifier, lineNumber); return tree; } void inorder(struct Node * tree) { if (tree == NULL) return; inorder(tree -> ltree); printf("Identifier: %s\nCounter: %d\nLines Appeared: [", tree -> data, tree -> counter); for (int i = 0; i < tree -> counter; i++) { printf("%d", tree -> lineList[i]); if (i != tree->counter - 1) { printf(", "); // 行号间加逗号分隔 } } printf("]\n\n"); inorder(tree -> rtree); } int main() { FILE * fp = fopen("test.txt", "r"); if (!fp) { // 检查文件是否打开成功 perror("无法打开文件"); return 1; } char buf[200]; char id[100]; int lineNumber = 1; int j; while (fgets(buf, sizeof(buf), fp)) { int i = 0; int len = strlen(buf); for (j = 0, i = 0; i < len; i++) { if (isalpha(buf[i]) || buf[i] == '_') { // 避免越界访问buf while (i < len && (isalnum(buf[i]) || buf[i] == '_')) id[j++] = buf[i++]; id[j] = '\0'; // 标识符字符串结尾 head = insert(head, id, lineNumber); j = 0; } } lineNumber++; // 每行处理完行号加1 } inorder(head); fclose(fp); // 关闭文件 // 可选:添加递归释放内存的函数,防止内存泄漏 return 0; }
运行输出(针对你的test.txt)
Identifier: Hello
Counter: 2
Lines Appeared: [4, 6]Identifier: Lochlann
Counter: 1
Lines Appeared: [5]Identifier: main
Counter: 1
Lines Appeared: [3]Identifier: printf
Counter: 3
Lines Appeared: [4, 5, 6]Identifier: include
Counter: 1
Lines Appeared: [1]Identifier: stdio
Counter: 1
Lines Appeared: [1]
内容的提问来源于stack exchange,提问作者lochlannoneill
相关产品推荐
相关产品推荐

