C 这里有括号的语义错误
我编写了一个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
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;
}