C语言AVL树项目:scanf导致输出多余换行问题求助
C语言AVL树程序多余换行问题解决(适配Moodle自动批改)
问题分析
你的代码中所有输出都使用printf("\n[xxx]")格式,即先打印换行再输出内容,这会导致程序启动后的第一个输出前多一个空行,也就是你遇到的“多余换行”问题。而如果把换行移到字符串末尾("[xxx]\n"),虽然能解决多余换行,但不符合Moodle的格式要求,因此需要找到一种既能保留“每个输出块单独成行”的格式,又不会产生开头空行的方案。
解决方案
核心思路是:第一个输出直接打印内容,后续每个输出前先打印换行。通过一个标志变量控制是否需要前置换行,既满足Moodle的格式要求,又消除多余空行。
步骤1:添加辅助打印函数和标志变量
在代码开头添加全局标志变量和可变参数打印函数(需要包含stdarg.h头文件):
#include <stdarg.h> // 标记是否是第一次输出 bool first_print = true; // 封装打印逻辑:第一次输出无前置换行,后续输出先换行再打印内容 void print_with_newline(const char* format, ...) { va_list args; if (!first_print) { printf("\n"); } else { first_print = false; } va_start(args, format); vprintf(format, args); va_end(args); }
步骤2:替换所有输出语句
将代码中所有printf("\n[xxx]")格式的语句,替换为print_with_newline("[xxx]"),去掉前置的\n。以下是关键函数的修改示例:
1. avl_insert函数修改
avl_node_t* avl_insert(avl_node_t* root, item_t ra, number nota){ bool rotacao_aplicada = false; bool* rotacao_aplicada_p = &rotacao_aplicada; root = priv_avl_insert(root, ra, nota, rotacao_aplicada_p); if(*rotacao_aplicada_p == false){ print_with_newline("[Ja esta balanceado]"); } return root; }
2. avl_rebalance函数修改
avl_node_t* avl_rebalance(avl_node_t* root, bool* rotacao_aplicada){ if (root == NULL) return root; if (get_balance(root) > 1) { //left *rotacao_aplicada = true; if (get_balance(root->left) >= 0){ print_with_newline("[No desbalanceado: %d]", root->ra); print_with_newline("[Rotacao: SD]"); print_with_newline("[x=%d y=%d z=%d]", root->left->left->ra, root->left->ra, root->ra); root = avl_left_left(root); } else { print_with_newline("[No desbalanceado: %d]", root->ra); print_with_newline("[Rotacao: DD]"); print_with_newline("[x=%d y=%d z=%d]", root->left->ra, root->left->right->ra, root->ra); root = avl_left_right(root); } } else if (get_balance(root) < -1) { //right *rotacao_aplicada = true; if (get_balance(root->right) <= 0){ print_with_newline("[No desbalanceado: %d]", root->ra); print_with_newline("[Rotacao: SE]"); print_with_newline("[x=%d y=%d z=%d]", root->ra, root->right->ra, root->right->right->ra); root = avl_right_right(root); } else { print_with_newline("[No desbalanceado: %d]", root->ra); print_with_newline("[Rotacao: DE]"); print_with_newline("[x=%d y=%d z=%d]", root->ra, root->right->left->ra, root->right->ra); root = avl_right_left(root); } } return root; }
3. 其他输出函数修改
同理修改avl_search、avl_find_height、avl_print_and_free等函数中的输出语句:
// avl_search示例 void avl_search(avl_node_t* root, int ra){ int comparacoes = 0; avl_node_t* no_buscado = priv_avl_binary_search(root, ra, &comparacoes); if(no_buscado == NULL){ print_with_newline("C=%d Nota=-1", comparacoes); } else { print_with_newline("C=%d Nota=%d", comparacoes, no_buscado->nota); } } // avl_find_height示例 void avl_find_height(avl_node_t* root){ int height = avl_height(root); print_with_newline("A=%d", height); } // avl_print_and_free示例 void avl_print_and_free(avl_node_t* root){ print_with_newline("["); avl_print_post_order(root); printf("]"); avl_destroy(root); }
原理说明
- 全局标志
first_print初始为true,第一次调用print_with_newline时,直接输出内容,不打印前置换行,同时将标志设为false。 - 后续调用该函数时,会先打印换行再输出内容,保证每个输出块单独成行,既符合Moodle的格式要求,又不会产生开头的多余空行。
内容的提问来源于stack exchange,提问作者user20013100
相关产品推荐
相关产品推荐

