一、问题描述
使用**#号法递归生成二叉树**时遇到一个scanf自动读取缓存中\n
的问题,导致程序无法按照设想的状态执行。
产生错误的代码如下:
//#号法前序创建二叉树
//test tree:
// AB#C##E#F##
// AB#CD##E#F##
// A
// B E
//# C # F
//
// D # #
// # #
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//Binary Tree node 二叉树结点
typedef struct BINARYNODE {
char ch; //结点值
struct BINARYNODE* lchild;//左子树
struct BINARYNODE* rchild;//右子树
}BinaryNode;
//Preorder traversal //前序
void Create_Recursion_DLR(BinaryNode* root)
{
if (root == NULL)
return;
//先访问根节点
printf("%c", root->ch);
//再访问左子树
Create_Recursion_DLR(root->lchild);
//再访问右子树
Create_Recursion_DLR(root->rchild);
}
//这个输入的用不了,很奇怪,唉 还没找到原因。艹艹艹
BinaryNode* CreateBinaryTree()
{
fflush(stdin);
char c;
scanf("%c", &c); //会在下一次递归时自动读入\n
//char clear[1000]; //起到清除缓存作用
//fgets(clear, 1000, stdin); //起到清除缓存作用
//gets(&c);
BinaryNode* node = NULL;
if (c == '#' )
{
node = NULL;
}
else
{
//前序生成树逻辑
node = (BinaryNode*)malloc(sizeof(BinaryNode));
node->ch = c;
node->lchild = CreateBinaryTree();
node->rchild = CreateBinaryTree();
}
return node;
}
BinaryNode* BinaryTreeCreate(char* arr, int* idx)
{
if (arr[*idx] == '#')
{
(*idx)++;//索引后移
return NULL;//为空返回null
}
BinaryNode* root = (BinaryNode*)malloc(sizeof(BinaryNode));//不为空创建节点,并根据当前索引赋数组值
root->ch = arr[*idx];
(*idx)++;//索引后移
root->lchild = BinaryTreeCreate(arr, idx);
root->rchild = BinaryTreeCreate(arr, idx);
return root;
}
void main()
{
char arr[] = "AB#C##E#F##";
//char arr[] = "A##";
int idx = 0;
BinaryNode * root = CreateBinaryTree();
Create_Recursion_DLR(root);
//BinaryNode* root1 = BinaryTreeCreate(arr, &idx);
//Create_Recursion_DLR(root1);
printf("\n");
system("pause");
}
二、错误原因
循环体中第二个scanf函数自动读入’\n’。产生的主要原因是 fflush(stdin);
未生效.貌似新版本gcc中这个语句都无效了。
可以用上面例子debug验证。
三、解决办法
-
将 scanf 用 gets替换解决。
gets()函数用来从标准输入设备(键盘)读取字符串直到回车结束, 但回车符 不属于这个字符串。
-
在scanf后加如如下代码
//可以将缓存中的\n读走,保证递归时不误读\n char clear[1000]; fgets(clear, 1000, stdin);