使用 scanf 在堆栈中推送操作

push operation in a stack with scanf

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

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

OUTPUT
    12 TNT
    13 ABC
    14 ESPN

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

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

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

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 提供的,则所有节点的字符串值都会更改为最后一个节点的字符串值。如果有人能告诉我问题出在哪里,我会很高兴。

看来,scanf("%c ", &j);,应该是scanf(" %c", &j);,否则会读到前一个scanf()留下的白色space,没有消耗掉那个您在 "%s" 说明符之后明确离开。

那只适用于"%c"说明符,"%s"说明符会在遇到白色space时停止,它期望" "即space 字符,而在 " %c" 中,isspace() 返回的任何白色 space 字符将被消耗,然后是您尝试捕获的输入字符。

代码需要在 push_ch(int id, char *str)

中复制 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;
}

也使用 答案来处理用户输入。