我正在尝试使用双向链表来模拟堆栈。 当我编写以下代码时,输出就是它应该是的。
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--;
}
此处temp1
和temp2
是固定大小的数组。我也在每次推送操作后调用显示功能来查看发生了什么。从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提供的,则所有节点的字符串值将更改为最后一个节点的字符串值。如果有人能告诉我问题在哪里,我会很高兴。
答案 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答案来处理用户输入。