C 这里有括号的语义错误

C 这里有括号的语义错误,c,function,parentheses,C,Function,Parentheses,我编写了一个C代码来检查简单的括号平衡,如果平衡,则分别打印NO和YES 问题是我得到的所有输入都是NO。因此,我认为这是一个语义错误,但找不到它(我已经尝试了2天:p) 有人能帮我吗?谢谢 #include <stdio.h> #include <stdlib.h> typedef struct stack { char s[1000]; int top; } STACK; void create(STACK *sptr) { sptr-&g

我编写了一个C代码来检查简单的括号平衡,如果平衡,则分别打印
NO
YES

问题是我得到的所有输入都是
NO
。因此,我认为这是一个语义错误,但找不到它(我已经尝试了2天:p)

有人能帮我吗?谢谢

#include <stdio.h>
#include <stdlib.h>

typedef struct stack {
    char s[1000];
    int top;
} STACK;

void create(STACK *sptr) {
    sptr->top = -1;
}

int isEmpty(STACK *sptr) {
    if (sptr->top == -1)
        return 1;
    else
        return 0;
}

void push(STACK *sptr, char data) {
    sptr->s[++sptr->top] = data;
}

char pop(STACK *sptr) {
    if (isEmpty(sptr) == 0)
        return sptr->s[sptr -> top];
    else
        return '$';
}

char *isBalanced(char *s, STACK *sptr) {
    char *y, *n;
    int i = 0;
    y = (char*)malloc(sizeof(char) * 4);
    y[0] = 'Y';
    y[1] = 'E';
    y[2] = 'S';
    y[3] = '\0';
    n = (char*)malloc(sizeof(char) * 3);
    n[0] = 'N';
    n[1] = 'O';
    n[2] = '\0';

    while (s[i] != '\0') {
        if (s[i] == '(' || s[i] == '{' || s[i] == '[') {
            push(sptr, s[i]);
        } else {
            char x = pop(sptr);
            switch (s[i]) {
              case ')':
                if (x != '(') 
                    return n;
                break;

              case '}':
                if (x != '{') 
                    return n;
                break;

              case ']':
                if (x != '[') 
                    return n;
                break;
            }
        }
        ++i;
    }

    if (isEmpty(sptr))
        return y;
    else
        return n;
}

int main() {
    STACK *sptr = (STACK *)malloc(sizeof(STACK));
    char c[21];
    int ch;
    do {
        printf("enter sequence:");
        scanf("%s", c);
        char *msg = isBalanced(c, sptr);
        printf("%s", msg);
        printf("choice?:");
        scanf("%d", &ch);
    } while(ch);
}
#包括
#包括
typedef结构堆栈{
chars[1000];
int top;
}堆叠;
无效创建(堆栈*sptr){
sptr->top=-1;
}
int isEmpty(堆栈*sptr){
如果(sptr->top==-1)
返回1;
其他的
返回0;
}
无效推送(堆栈*sptr,字符数据){
sptr->s[++sptr->top]=数据;
}
字符pop(堆栈*sptr){
如果(isEmpty(sptr)==0)
返回sptr->s[sptr->top];
其他的
返回“$”;
}
char*isBalanced(char*s,STACK*sptr){
字符*y,*n;
int i=0;
y=(字符*)malloc(大小(字符)*4);
y[0]=“y”;
y[1]=‘E’;
y[2]=‘S’;
y[3]='\0';
n=(char*)malloc(sizeof(char)*3);
n[0]=‘n’;
n[1]=‘O’;
n[2]='\0';
而(s[i]!='\0'){
如果(s[i]='('| | s[i]='{'| | s[i]=='[')){
推动(sptr,s[i]);
}否则{
char x=pop(sptr);
开关(s[i]){
案例“)”:
如果(x!='(')
返回n;
打破
案例“}”:
如果(x!='{')
返回n;
打破
案例']':
如果(x!='[')
返回n;
打破
}
}
++一,;
}
如果(isEmpty(sptr))
返回y;
其他的
返回n;
}
int main(){
STACK*sptr=(STACK*)malloc(sizeof(STACK));
charc[21];
int-ch;
做{
printf(“输入顺序:”);
scanf(“%s”,c);
char*msg=isBalanced(c,sptr);
printf(“%s”,msg);
printf(“选择:”);
scanf(“%d”和“ch”);
}while(ch);
}
更新代码:

#包括
#包括
typedef结构堆栈{
chars[1000];
int top;
}堆叠;
无效创建(堆栈*sptr){
sptr->top=-1;
}
int isEmpty(堆栈*sptr){
如果(sptr->top==-1)
返回1;
其他的
返回0;
}
无效推送(堆栈*sptr,字符数据){
sptr->s[++sptr->top]=数据;
}
字符pop(堆栈*sptr){
如果(isEmpty(sptr)==0)
返回sptr->s[sptr->top--];
其他的
返回“$”;
}
int isBalanced(字符*s,堆栈*sptr){
int i=0;
而(s[i]!='\0'){
如果(s[i]='('| | s[i]='{'| | s[i]=='[')){
推动(sptr,s[i]);
}否则{
char x=pop(sptr);
开关(s[i]){
案例“)”:
如果(x!='(')
返回0;
打破
案例“}”:
如果(x!='{')
返回0;
打破
案例']':
如果(x!='[')
返回0;
打破
}
}
++一,;
}
如果(isEmpty(sptr))
返回1;
其他的
返回0;
}
int main(){
STACK*sptr=malloc(sizeof(STACK));
charc[21];
int-ch;
做{
printf(“输入顺序:”);
scanf(“%s”,c);
printf(“%s”)(isBalanced(c,sptr)?“是”:“否”);
printf(“选择:”);
scanf(“%d”和“ch”);
}while(ch);
}

pop
函数中,您没有递减
top
,因此
isEmpty
函数始终返回
false

因此,您总是返回
no

char* isBalanced(char* s, STACK* sptr)
{
    ....

   if(isEmpty(sptr)) return y;
   else return n;
}

以下是正确的实现:

char pop(STACK* sptr)
{
    if(isEmpty(sptr) == 0)
        return sptr->s[sptr->top--];
    else
        return '$';
}

我会添加标志,看看哪一个不匹配

unsigned match(const char *f)
{
    int p = 0,s = 0,b = 0;
    while(*f)
    {
        switch(*f++)
        {
            case '(':
                p++;
                break;
            case ')':
                p -= !!p;
                break;

            case '[':
                s++;
                break;
            case ']':
                s -= !!s;
                break;

            case '{':
                b++;
                break;
            case '}':
                b -= !!b;
                break;
            default:
                break;
        }
    }
    return (!p) | ((!s) << 1) | ((!b) << 2);
}
无符号匹配(常量字符*f)
{
int p=0,s=0,b=0;
而(*f)
{
开关(*f++)
{
格“(”:
p++;
打破
案例“)”:
p-=!!p;
打破
案例“[”:
s++;
打破
案例']':
s-=!!s;
打破
案例“{”:
b++;
打破
案例“}”:
b-=!!b;
打破
违约:
打破
}
}

return(!p)|((!s)我假设这样的想法:总是允许打开一个paren(在分析的文本中),但是关闭一个paren必须匹配最后一个打开的paren。这就是为什么需要一个堆栈。另外,如果堆栈不是空的,那么最后意味着一些paren没有关闭

因此,您应该使用堆栈,但仅当您遇到paren时(打开或关闭)

在函数isBalanced()中,主循环可以是:

while (s[i] != '\0') {
    if ( s[i] == '(' || s[i] == '{' || s[i] == '[' ) {
        // opening - remember it
        push(sptr, s[i]);
    } else if ( s[i] == ')' || s[i] == '}' || s[i] == ']' ) {
        // closing - it should match
        if ( ! popmatch(sptr, s[i]) )
          return n;
    }
    ++i;
}
函数的其余部分正常。现在,我修改了pop()函数:重命名为popmatch,因为它应该检查参数是否与堆栈顶部匹配。如果匹配,则弹出堆栈并返回ok。因此,函数为:

char popmatch(STACK* sptr, char c) {
    // an empty stack can not match
    if (isEmpty(sptr))
      return 0;

    // not empty, can check for equality
    if ( c =! sptr->s[sptr->top] )
      return 0;
      // does not match!

    // ok, it matches so pop it and return ok
    sptr->top--;
    return 1;
}

请注意,代码很好地反映了“分析”;当分析简短明了,并且代码遵循分析时,结果通常也简短明了。

以下是代码中的一些主要问题:

  • 在使用之前,您没有使用
    create(sptr)
    正确初始化堆栈,最好是在定义堆栈的
    main()
    中。您的代码具有未定义的行为。它偶然打印
    NO
    ,可能是因为
    sptr->top
    的初始值为
    0
    ,这使得堆栈非空

  • 只有当遇到结束分隔符
    ]
    }
    时,才应从堆栈中弹出

  • 您应该告诉
    scanf()
    要读入
    c
    的最大字符数:
    scanf(“%20s”,c)
    ,以防止潜在的缓冲区溢出
    char popmatch(STACK* sptr, char c) {
        // an empty stack can not match
        if (isEmpty(sptr))
          return 0;
    
        // not empty, can check for equality
        if ( c =! sptr->s[sptr->top] )
          return 0;
          // does not match!
    
        // ok, it matches so pop it and return ok
        sptr->top--;
        return 1;
    }
    
    #include <stdio.h>
    
    typedef struct stack {
        char s[1000];
        int top;
    } STACK;
    
    void create(STACK *sptr) {
        sptr->top = -1;
    }
    
    int isEmpty(STACK *sptr) {
        if (sptr->top == -1)
            return 1;
        else 
            return 0;
    }
    
    void push(STACK *sptr, char data) {
        sptr->s[++sptr->top] = data;
    }
    
    char pop(STACK *sptr) {
        if (isEmpty(sptr) == 0)
            return sptr->s[sptr->top--];
        else
            return '$';
    }
    
    int isBalanced(char *s, STACK *sptr) {
        int i;
    
        for (i = 0; s[i] != '\0'; i++) {
            switch (s[i]) {
              case '(':
              case '{':
              case '[':
                push(sptr, s[i]);
                break;
              case ')':
                if (pop(sptr) != '(')
                    return 0; 
                break;
              case '}':
                if (pop(sptr) != '{') 
                    return 0;
                break;
              case ']':
                if (pop(sptr) != '[') 
                    return 0;
                break;
            }
        }
        return isEmpty(sptr);
    }
    
    int main() {
        STACK s, *sptr = &s;
        char c[100];
        int ch;
    
        do {
            printf("Enter sequence: ");
            if (scanf(" %99[^\n]", c) != 1)
                break;
            create(sptr);
            printf("%s\n", isBalanced(c, sptr) ? "YES" : "NO");
            printf("Choice? ");
            if (scanf("%d", &ch) != 1)
                break;
        } while (ch);
    
        return 0;
    }