使用scanf在堆栈中执行操作

时间:2015-05-21 14:32:21

标签: c struct stack

我正在尝试使用双向链表来模拟堆栈。 当我编写以下代码时,输​​出就是它应该是的。

    push_ch(12, "TNT");
    push_ch(13, "ABC");
    push_ch(14, "ESPN");
    display();

OUTPUT
    12 TNT
    13 ABC
    14 ESPN

但是,当从stdin提供参数时,我遇到了问题。 输入的示例是:

3 --> number of operations
push c 12 TNT
push c 13 ABC
push c 14 ESPN

在main函数中,我写了这些来获取参数。

scanf("%d", &i);
while(i){
    scanf("%s ", temp1);
    if(!strcmp(temp1, "push")){
        scanf("%c ", &j);
        if(j == 'c'){
            scanf("%d %s[^\n]", &k, temp2);
            push_ch(k, temp2);
            display();
        }
     }
i--;
}

此处temp1temp2是固定大小的数组。我也在每次推送操作后调用显示功能来查看发生了什么。从stdin提供输入时的输出是:

12 TNT
//stack after first push
12 ABC
13 ABC
//stack after second push
12 ESPN
13 ESPN
14 ESPN
//stack after third push

如您所见,在第二次推送时,第一个元素已经改变。同样,在第三次推送时,前两个元素已被修改。他们的频道号码没有问题。他们应该以某种方式存在。

这是频道定义

typedef struct channel {
    struct channel * next;
    struct channel * back;
    int c_id;
    char * c_name;
    program * head_p;
    program * current_p;
} channel;

这是我写的push_ch函数。请忽略它不是O(1)。

void push_ch(int id, char *str){
    channel *temp;
    temp = head_c;
    if(temp == NULL){
        temp = malloc(sizeof(channel));
        temp->c_id = id;
        temp->c_name = str;
        temp->next = NULL;
        temp->back = NULL;
        temp->head_p = NULL;
        temp->current_p = NULL;
        head_c = temp;
    }
    else{
        while((temp->next) != NULL){
            temp = temp->next;
        }
        temp->next = malloc(sizeof(channel));
        temp->next->c_id = id;
        temp->next->c_name = str;
        temp->next->next = NULL;
        temp->next->head_p = NULL;
        temp->next->current_p = NULL;
        temp->next->back = temp;
    }
}

总而言之,当我多次手动调用push函数将项添加到堆栈时没有问题。但是,如果输入是从stdin提供的,则所有节点的字符串值将更改为最后一个节点的字符串值。如果有人能告诉我问题在哪里,我会很高兴。

2 个答案:

答案 0 :(得分:1)

scanf("%c ", &j);似乎应该是scanf(" %c", &j);,因为否则它会读取前一个scanf()留下的空白区域,它不会消耗您之后明确留下的空白区域。 "%s"说明符。

仅适用于"%c"说明符,"%s"说明符在遇到空格时会停止,并且它需要" "即空格字符,而在{{1 }}," %c"返回的任何空白字符都将被消耗,然后是您尝试捕获的输入字符。

答案 1 :(得分:1)

代码需要在str

中复制push_ch(int id, char *str)

示例:

char *str_dup = strdup(str);
...
temp->c_name = str_dup;
...
temp->next->c_name = str_dup;

如果strdup()不可用,请自行制作

char *my_strdup(const char *s) {
  if (s) {
    size_t length = strlen(s) + 1;
    char *newptr = malloc(length);
    if (newptr) {
      return memcpy(newptr, s, length);
    }
  }
  return NULL;
}

还可以使用@iharob答案来处理用户输入。