扫描堆栈中的字符时遇到错误

时间:2015-01-25 16:51:29

标签: c++ c

#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 。通过这种方式,我在堆栈元素中自动将空格作为字符,并且顶部变得加倍。请帮我解决一下这个。您可以编辑它并自行检查。

2 个答案:

答案 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;) 。您可以在知情的基础上进行例外处理,但要注意按价值传递大型结构的隐性成本。此外,对通过值传递的结构所做的更改不会反映在调用函数中。你通过返回修改后的值来绕过它,但要小心。