2013-08-22 208 views
-2

我正在使用c中的双向链表来制作树。 我在该函数中使用递归调用,但不知何故它不起作用。 我的代码是:scanf()不在等待用户输入

struct node 
{ 
    int data; 
    struct node *right; 
    struct node *left; 
}; 

struct node* getNode() 
{ 
    struct node *temp; 
    temp= (struct node *)malloc(sizeof(struct node)); 
    temp->right=NULL; 
    temp->left=NULL; 
    return temp; 
} 

这里在下面的功能我得到的问题。

struct node* maketree() 
{ 
    struct node *t; 
    t=getNode(); 
    int value; 
    char choice1='n',choice2='n'; 
    printf("\nenter the value to the node"); 
    scanf("%d",&value); 
    t->data=value; 
    printf("\nis there any left child??\n"); 
    scanf("%c",&choice1);    // I think here my problem is . 
    if (choice1 == 'y') 
    { 
     t->left=maketree(); 
    } 

    printf("\nis there any right child??\n"); 
    scanf("%c",&choice2); 
    if (choice2 == 'y' || choice2 == 'Y') 
    { 
     t->right=maketree(); 

    } 
    return t; 
} 

int main (void) 
{ 
    struct node *t; 
    t=maketree(); 
    return; 
} 

代码编译正确,但问题是,代码不等待我的选择(我用scanf(),C应该等待,直到我进入输入端子)。 但输出是:

enter the value to the node4 

is there any left child?? 

is there any right child?? 

请协助。

+1

如果您检查了'scanf()'验证的返回码,那么您现在可能已经发现了该问题。 – WhozCraig

+1

Aaaaaand kaboom。如果你不明白它是如何工作的,使用'fgets()'和**离开'scanf()'**。这不是初学者的功能。 – 2013-08-22 05:41:53

+0

[scanf第二次不会要求输入]的可能重复(http://stackoverflow.com/questions/13372923/scanf-wont-ask-for-input-the-second-time)以及[Program doesn不要等待用户输入scanf(“%c”,&yn);](http://stackoverflow.com/questions/8464620/program-doesnt-wait-for-user-input-with-scanfc-yn)和[为什么scanf在一次失败后不等待用户输入?](http://stackoverflow.com/questions/11805414/why-does-scanf-not-wait-for-user-input-after-it-fails-一次性) – 2013-08-22 05:45:56

回答

4

scanf("%d", &value)在后面留下换行符; scanf("%c", &choice1)读取换行符。

每次检查scanf()的返回值。并打印您阅读的内容以帮助您调试代码。确保你的程序得到你认为它的结果。

一个简单的解决方法是用scanf(" %c", &choice1)替换第二个scanf()。格式字符串中的空白会占用空白区域,包括换行符,并读取第一个非空白字符。当然,它也留下了一条新线。

正如在评论中暗示,它通常是比较容易控制的东西:

char line[4096]; 

if (fgets(line, sizeof(line), stdin) == 0) 
    ...deal with EOF... 

然后你就可以使用sscanf()解析线。这种通用技术比直接使用scanf()要容易出错。当您将整行添加到错误报告中时,连贯地报告错误也更容易。当您每次拨打scanf()时,您都要阅读多次转化。

0

问题是,\r被发送到第二个scanf,它是从第一个scanf剩下的。

而且由于您只读取了一个带有scanf的字符(这是BTW不建议 - 使用getchar()代替)它接受回车符(\r)。 如果您仍然想要使用第二个scanf,请在第一个scanf()后立即对标准输入进行刷新:fflush(stdin)

0

scanf()没什么错,学习使用它是阅读文档的一个很好的练习,但它确实有效。学习使用它是程序员做的一个很好的例子!

作为第一个猜测,尝试在你的代码中的这些语句:

char &choice1[2]; // allow for %c\0, but even this can be avoided 
// etc. 
scanf("%1s", &choice1); 
if (tolower(choic1[0]) == 'y') { // etc. 

%1s读取和丢弃的白色空间,包括新的生产线,以及1限制了有资格作为一个字符串的字符数。

如果此更改无效,请告诉我,我将测试/使用您的代码来查找修复程序。