You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从结构体函数返回结构体?C语言BST程序函数报错排查

修复二叉搜索树单词存储程序的错误

修复后的完整代码

//The Last attempt//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct WordNode {
  char* word;  // 修改为指针存储完整字符串
  int line;
  struct WordNode* left;
  struct WordNode* right;
};

// 返回类型改为结构体指针
struct WordNode* createNode(char* word, int line) {
  struct WordNode* node = malloc(sizeof(struct WordNode));
  if (node == NULL) {  // 新增内存分配失败检查
    perror("Failed to allocate memory");
    exit(EXIT_FAILURE);
  }
  node->word = strdup(word);  // 拷贝字符串,避免指向栈内存
  node->line = line;
  node->left = NULL;
  node->right = NULL;
  return node;
}

// 返回类型改为结构体指针
struct WordNode* insert(struct WordNode* root, char* word, int line) {
  if (root == NULL) {
    return createNode(word, line);
  }

  int cmp = strcmp(word, root->word);
  if (cmp == 0) {
    // 单词已存在,直接返回原节点
    return root;
  } else if (cmp < 0) {
    root->left = insert(root->left, word, line);
  } else {
    root->right = insert(root->right, word, line);
  }

  return root;
}

int main(int argc, char* argv[]) {  // 修正argv参数类型
  if (argc != 2) {
    printf("Usage: %s <filename>\n", argv[0]);
    return 1;
  }

  char* filename = argv[1];  // 修正文件名变量类型
  FILE *file = fopen(filename, "r");  // 使用命令行传入的文件名,移除硬编码路径
  if (file == NULL) {
    perror("Error opening file");
    return 1;
  }

  struct WordNode *root = NULL;

  char line[256];
  int lineNumber = 1;
  while (fgets(line, sizeof(line), file)) {
    char* word = strtok(line, " \n\t");  // 修正word变量类型
    while (word != NULL) {
      root = insert(root, word, lineNumber);
      word = strtok(NULL, " \n\t");
    }
    lineNumber++;
  }

  fclose(file);

  // 可选:添加中序遍历函数,按字母顺序打印单词和行号,验证功能正确性

  return 0;
}

关键错误修复说明

  • 返回类型不匹配:原createNode()和insert()声明返回struct WordNode结构体,但实际返回的是指针。直接返回结构体不仅有拷贝开销,还会触发类型错误,因此将两个函数的返回类型改为struct WordNode*。
  • 字符串存储错误:原结构体中char word只能存单个字符,无法保存完整单词,改为char* word;创建节点时必须用strdup()(或malloc+strcpy)拷贝字符串,避免直接赋值指向栈内存的临时字符串,防止后续内存访问异常。
  • 参数类型错误:
    • main函数的argv参数应为char* argv[],原代码写成char argv[]会导致命令行参数解析失败;
    • filename和strtok返回的word都应为char*类型,原代码用char会截断字符串。
  • 硬编码路径问题:原代码写死文件路径,改为使用命令行传入的argv[1],提升程序通用性。
  • 内存安全检查:新增malloc失败的判断,避免空指针访问导致程序崩溃。

内容的提问来源于stack exchange,提问作者Younes ChebraHenni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 18:55:28