#include <stdio.h>
#define MAXLEN 100
typedef struct
{
char element[MAXLEN];
int top;
} stack;
stack init(stack s)
{
s.top=-1;
return s;
}
int isEmpty(stack s){
return(s.top==-1);
}
int isFull(stack s){
return (s.top==MAXLEN-1);
}
stack push(stack s,char ch){
if(s.top==MAXLEN-1){
printf("\n the stack is full\n");
return s;
}
else{
++s.top;
s.element[s.top]=ch;
return s;
}
}
stack pop(stack s){
if(s.top==-1){
printf("\n the stack is empty");
return s;
}
else{
--s.top;
return s;
}
}
void top(stack s){
if(s.top==-1){
printf("\n empty stack");
}
else
printf("%c",s.element[s.top]);
}
void print(stack s){
int i;
printf(" serial no character ");
for(i=0;i<s.top;++i){
printf(" %d %c \n",i,s.element[i]);
}
}
int main(){
stack s;
s.top=-1;
init(s);
char e;
int n,j=1,k;
while(j==1){
printf("\n enter your choice 1.push 2.pop 3.top 4.print 5.exit:");
scanf("%d",&n);
switch(n)
{
case 1:
printf("\n enter the element to be pushed: ");
scanf("%ch",&e);
s=push(s,e);
break;
case 2:
s=pop(s);
break;
case 3:
top(s);
break;
case 4:
print(s);
break;
case 5:
j=0;
break;
default:
printf("\n wrong choice entered enter correct one ");
break;
}
}
}
编译并运行它并扫描了一个字符后发生错误;它离开了交换机并且没有连续扫描n
的值,只是进入具有预先指定值的交换机,它从交换机出来并要求n
输入t 。通过这种方式,我在堆栈元素中自动将空格作为字符,并且顶部变得加倍。请帮我解决一下这个。您可以编辑它并自行检查。
答案 0 :(得分:1)
更改
scanf("%ch",&e); /* %ch ? */
要
scanf(" %c",&e); // notice a whitespace in the format string
当scanf("%c",&e);
留下换行符时,会再次使用。
告诉scanf忽略空格。
OR
if (scanf(" %c",&e) != 1)
//Print error
答案 1 :(得分:0)
使代码正常工作并不需要花费太多精力。在下面的固定代码中,由于我使用的编译器选项,我预先声明了函数。另一种方法是将函数定义为static
。
#include <stdio.h>
#define MAXLEN 100
typedef struct
{
char element[MAXLEN];
int top;
} stack;
int isEmpty(stack s);
int isFull(stack s);
stack init(stack s);
stack pop(stack s);
stack push(stack s, char ch);
void print(stack s);
void top(stack s);
stack init(stack s)
{
s.top = -1;
return s;
}
int isEmpty(stack s)
{
return(s.top == -1);
}
int isFull(stack s)
{
return(s.top == MAXLEN - 1);
}
stack push(stack s, char ch)
{
if (s.top == MAXLEN - 1)
{
printf("the stack is full\n");
}
else
{
++s.top;
s.element[s.top] = ch;
}
return s;
}
stack pop(stack s)
{
if (s.top == -1)
{
printf("the stack is empty\n");
}
else
{
--s.top;
}
return s;
}
void top(stack s)
{
if (s.top == -1)
printf("empty stack\n");
else
printf("TOS: %c\n", s.element[s.top]);
}
void print(stack s)
{
int i;
printf("serial no character\n");
for (i = 0; i <= s.top; ++i)
{
printf(" %3d %c\n", i, s.element[i]);
}
}
int main(void)
{
stack s;
s.top = -1;
init(s);
char e;
int n, j = 1;
while (j == 1)
{
printf("\nenter your choice 1.push 2.pop 3.top 4.print 5.exit: ");
if (scanf("%d", &n) != 1)
{
fprintf(stderr, "Failed to read a number.\n");
return 1;
}
switch (n)
{
case 1:
printf("\nenter the element to be pushed: ");
if (scanf(" %c", &e) != 1)
{
fprintf(stderr, "Failed to read a character.\n");
return 1;
}
s = push(s, e);
break;
case 2:
s = pop(s);
break;
case 3:
top(s);
break;
case 4:
print(s);
break;
case 5:
j = 0;
break;
default:
printf("incorrect choice (%d not in range 1-5); enter correct one\n", n);
break;
}
}
return 0;
}
除了使缩进保持一致(我使用uncrustify
,但也有other tools也能完成这项工作),我在scanf()
语句中添加了错误检查,修复了{ {1}}格式字符串("%ch"
是多余的,尽管大多数是无害的),从打印中删除了尾随空格,在非提示h
语句的末尾使用了换行符。
您的打印代码打印不够;由于您运行堆栈指针的方式,您需要使用printf()
而不是for (i = 0; i <= s.top; i++)
打印<=
。使用<
的更正统的方法是显示下一个要使用的空间(因此数字从零开始并上升到MAXLEN)。必须进行一系列相应的更改。
然而,还有一些重大的好奇心。您继续按值传递堆栈并按值返回它们,而不是通过指针传递它们。因此,您可以将104个字节传入和传出函数,这是非常多的。在这段代码中,效率并不是一个大问题,但我们说,这种风格是非正统的。您在top
中的初始化节也存在问题:
main()
第一行很好。第二行设置stack s;
s.top = -1;
init(s);
,就&#34而言是正常的;它可以工作&#34;但是违反了封装。下一行存在多个问题。它需要已初始化堆栈的副本,将top
设置为top
,并返回修改后的值。但是,您的调用代码会忽略返回的值。
如果你传递了指向你的功能的指针,你可以使用:
-1
然后:
void init(stack *s)
{
s->top = -1;
}
如果您传递值,则可以使用:
stack s;
init(&s);
虽然这有点没用,你可以使用:
stack s;
s = init(s);
然后致电:
stack init(void)
{
stack s;
s.top = -1;
return s;
}
其中,通过指针传递是较大结构的常规机制(如果要求指定&#39;较大&#39;,我说&#34; 16字节或更多&#34;) 。您可以在知情的基础上进行例外处理,但要注意按价值传递大型结构的隐性成本。此外,对通过值传递的结构所做的更改不会反映在调用函数中。你通过返回修改后的值来绕过它,但要小心。