C程序在scanf上无限等待

5

我有一个实现栈的C程序。

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


struct node{
    int data;
    struct node *link;
};

struct stack{
    struct node *head;
    struct node *data_node;
};

int push(struct stack *a_stack, int i){
    a_stack->data_node = malloc(sizeof(struct node));
    if(a_stack->data_node == NULL){
        puts("Error: Cannot allocate sufficient memory.");
        exit(1);
    }
    a_stack->data_node->data = i;
    a_stack->data_node->link = a_stack->head;
    a_stack->head= a_stack->data_node;
    return 0;
}

int pop(struct stack *a_stack){
    if(a_stack->head==NULL){
        return '\n';
    }
    int temp = a_stack->head->data;
    a_stack->data_node = a_stack->head;
    a_stack->head = a_stack->head->link;
    free(a_stack->data_node);
    return temp;
}

int minimum(struct stack *a_stack){
    if(a_stack->head==NULL){
        return '\n';
    }
    int min = a_stack->head->data;
    struct node *a_node = a_stack->head;
    while(a_node!=NULL){
        if(min>a_node->data){
            min = a_node->data;
            a_node = a_node->link;
        }
    }
    return min;
}

int init_stack(struct stack *a_stack){
    a_stack->head = NULL;
    a_stack->data_node = NULL;
}

int handle_input(struct stack *test){

    char* input_string = (char*)malloc(20);
    scanf("%s", input_string);
    // gets(input_string);

    char* pop_cmd = "-";
    char* min_cmd = "min";
    int num;

    if (strcmp(pop_cmd, input_string) == 0){
        printf("%d\n", pop(test));
    }

    else{
        if (input_string[0] == 'm'){
            printf("%d\n", minimum(test));
        }
        else{
            num = atoi(input_string);
            push(test, num);
        }   
    }

    return 0;
}


int main(void){

    int no_of_input, counter;

    struct stack test;
    init_stack(&test);

    scanf("%d", &no_of_input);

    for(counter=no_of_input; counter>0; counter=counter-1){
        handle_input(&test);
    };

    return 0;
}

问题是,当我想输入“min”,这是用于计算数组最小元素的命令时,程序会在输入上无限等待。经过一番搜索,我仍然不知道为什么会发生这种情况。


你的handle_input方法中使用了char指针,这会导致问题吗? char* input_string = (char*)malloc(20); scanf("%s", input_string); - user2277872
在大多数系统上,scanf函数不会返回,直到您键入回车键。(这被称为行缓冲。)您是否这样做了? - Gene
@Gene 是的。我已经尝试了回车和Ctrl + D。但仍然没有任何反应。 - tarashish
2
不要使用 scanf()。请参考 man 3 fgets - user529758
避免使用fgets()函数导致缓冲区溢出,而使用scanf()函数读取一行不好吗? - Grijesh Chauhan
2个回答

4

scanf函数不等待输入,但你却遇到了无限循环问题。在函数minimum()中,你只有在条件满足的情况下才会将a_node更新为下一个链表节点:

  int min = a_stack->head->data;  //note
  struct node *a_node = a_stack->head; //note

   while(a_node!=NULL){
        if(min > a_node->data){<-- "Always evaluates FALSE because: min is a_node->data"
            min = a_node->data;
            a_node = a_node->link; <--"Should NOT be here"
        }
        a_node = a_node->link; <--"but it should be here"
    }

此外,if条件(min > a_node->data)总是评估为false,因为:

mina_stack->head->dataa_nodea_stack->head,所以min == a_node->datemin > a_node->data总是评估为false,因为你在if主体中更新了a_node

此外,我发现handle_input()函数存在内存泄漏。你应该显式地释放动态分配的内存。请阅读下面的建议:

int handle_input(struct stack *test){
    char* input_string = malloc(20); <-- "No need to type case"  
    // code here
    free(input_string);  <-- "Add this"
    return 0;
}

没错,就是这样。有点儿傻。我会在大约5分钟后接受你的答案,因为那时候我才被允许。谢谢 :) - tarashish
但是我猜修复第一个问题会自动解决第二个情况。 - tarashish
2
@tarashish 不,你只有第一个问题,第二个只是让你的代码执行了一个不必要的迭代! - Grijesh Chauhan
第一次迭代时,条件仍然无用。 - tarashish

0

另外,在:

int init_stack(struct stack *a_stack){
    a_stack->head = NULL;
    a_stack->data_node = NULL;
}

我认为它应该返回void而不是int。

handle_input()中的min_cmd未使用。


是的,同意。min_cmd和handle_input在代码中被使用,只是在这个版本中没有被用到。 - tarashish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接