使用 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--;
}
这里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 提供的,则所有节点的字符串值都会更改为最后一个节点的字符串值。如果有人能告诉我问题出在哪里,我会很高兴。
看来,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;
}
也使用 答案来处理用户输入。
我正在尝试使用双向链表模拟堆栈。 当我编写以下代码时,输出就是它应该的样子。
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--;
}
这里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 提供的,则所有节点的字符串值都会更改为最后一个节点的字符串值。如果有人能告诉我问题出在哪里,我会很高兴。
看来,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;
}
也使用