编写一程序检查C源程序文件中{}、()等括号是否匹配,并输出检测到的不匹配的括号及所对应括号与所在的行号

2 篇文章 0 订阅
1 篇文章 0 订阅

前言

括号匹配问题算是栈应用中比较经典的问题了,在数据结构的书中还有各种考试中会出现。最近刷题的时候也遇到了,就想写一篇文章整理一下。

代码

方法一:这里我使用了两个栈进行括号匹配的核心算法

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
#define STACK 20
#define STACKINCREMENT 10
static int line_number = 1,i=0,j=0;
typedef struct
{
    char *base;         // 栈底指针
    char *top;          // 栈顶指针
    int stackSize;      // 栈大小
    int a[1000];
} sqStack;
 
void InitStack(sqStack *s)
{
    s->base = (char *)malloc(STACK * sizeof(char));  // 为栈分配内存
    if (!s->base)
        exit(0);  // 分配失败则退出程序
    s->top = s->base;
    s->stackSize = STACK;
}
 
void Push(sqStack *s, char e)
{
    if (s->top - s->base >= s->stackSize)
    {
        s->base = (char *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(char));  // 栈满时重新分配内存
       // if (!s->base)
         //   exit(0);
        s->top = s->base + s->stackSize;
        s->stackSize = s->stackSize + STACKINCREMENT;
    }
    *(s->top) = e;   // 将元素压入栈顶
    s->top++;
}
 
int Pop(sqStack *s, char *e)
{
    if (s->top == s->base)
        return 1;  // 栈空,出栈失败
    *e = *--(s->top);  // 弹出栈顶元素
    return 0;
}
int match(char e, char c)  
{
    if( e=='(' && c==')' )
        return 1;
    return 0;
}
int match1(char e, char c)  
{
    if( e=='{' && c=='}' )
        return 1;
    return 0;
}
int StackLen(sqStack s)
{
    return (s.top - s.base);  // 返回栈长度
}
 
int main()
{
    sqStack s,ss;
    char c, e;
    InitStack(&s);
    InitStack(&ss);
    printf("Please enter the name of the file: ");
    char filename[100];
    scanf("%s", filename);
 
    FILE *file = fopen(filename, "r");
    if (!file)
    {
        printf("File not found or cannot be opened.\n");
        return 1;  // 无法打开文件,程序退出
    }
	int n = 0;
    while ((c = fgetc(file)) != EOF)
    {
        if(c=='/'){
            c=fgetc(file);
            if(c=='*'){
            do{c = fgetc(file);}while(c!='*');
            }
        }
        if (c == '\n')
        {
            line_number++;  // 更新行号
            continue;
        }
 
        if( c=='(' || c==')' )
        {                        // 如果是括号,就进栈
            if( !StackLen(s) )   //如果栈的长度为空,c直接进栈
            {
                Push(&s, c);     //存入c  
            }
            else                   //如果c放入时,栈已经不空了,
            {
                Pop(&s, &e);
                     //取出栈顶元素来判断与新放入的c是否匹配
                if( !match(e, c) )
                    //如果match执行结果为假,即不匹配
                {
                    Push(&s, e);
                    //原栈顶元素重新入栈
                    Push(&s, c);
                    s.a[i++]=line_number;
                    //将输入的括号字符入栈
                }
              else if(match(e,c))
                {
                    i--;
                }
            }
        }
     else if( c=='{' || c=='}' )
        {                        // 如果是括号,就进栈
            if( !StackLen(ss) )   //如果栈的长度为空,c直接进栈
            {
                Push(&ss, c);     //存入c  
            }
            else                   //如果c放入时,栈已经不空了,
            {
                Pop(&ss, &e);
                     //取出栈顶元素来判断与新放入的c是否匹配
                if( !match1(e, c) )
                    //如果match执行结果为假,即不匹配
                {
                    Push(&ss, e);
                    //原栈顶元素重新入栈
                    Push(&ss, c);
                    ss.a[j++]=line_number;
                    //将输入的括号字符入栈
                }
                else if(match1(e,c))
                {
                    j--;
                }
            }
        }
    }
    fclose(file);
 	for(Pop(&s, &e),i=i-1;e;Pop(&s, &e),i--)
   	 {
    	  printf("Unmatched %c at end of file in line %d\n", e, s.a[i]);  // 输出未匹配的括号错误
    	  n++;
          strcpy(&e,"\0");
   	 }
    for (Pop(&ss, &e),j=j-1;e;Pop(&ss, &e),j--)
   	 {
    	  printf("Unmatched %c at end of file in line %d\n", e, ss.a[j]);  // 输出未匹配的括号错误
    	  n++;
          strcpy(&e,"\0");
   	 }
	if (n == 0)
    {
        printf("All parentheses in the input file match exactly.\n");  // 输出所有括号匹配正确
    }
    else
    {
        printf("There are unmatched parentheses in the input file.\n");  // 输出存在未匹配括号的错误
    }
    return 0;
}

 方法二:适合简单方面的括号匹配(易看懂)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define STACK 20
#define STACKINCREMENT  10
typedef struct
{
    char *base;//栈底   
    char *top; //栈顶    
    int stackSize;
}sqStack;
InitStack(sqStack *s)    
{
    s->base = (char *)malloc(STACK * sizeof(char));
    if( !s->base )       
        exit(0);         
    s->top = s->base;    
    s->stackSize = STACK;
}                       
Push(sqStack *s, char e)              
{
    if( s->top - s->base >= s->stackSize )
    {                                     
        s->base = (char *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(char));
        if( !s->base )                  
            exit(0);                    
        s->top = s->base + s->stackSize; 
        s->stackSize = s->stackSize + STACKINCREMENT;
    }
    *(s->top) = e;     
    s->top++;          
}
Pop(sqStack *s, char *e)    
{
    if( s->top == s->base )     
        return 1;             
    *e = *--(s->top);         
}
int StackLen(sqStack s)      
{
    return (s.top - s.base); //返回长度:顶-底
}
int match(char e, char c)  
{
    if( e=='(' && c==')' )
        return 1;
    if( e=='{' && c=='}' )
        return 1;
    return 0;
}
int main()                       
{
    sqStack s;//栈
    char c, e;                
    InitStack( &s );//初始化
    printf("Please enter the program:");
    scanf("%c", &c);             
    while( c !='@')
    {
        if( c=='(' || c==')' || c=='{' || c=='}' )
        {                        // 如果是括号,就进栈
            if( !StackLen(s) )   //如果栈的长度为空,c直接进栈
            {
                Push(&s, c);     //存入c
            }
            else                   //如果c放入时,栈已经不空了,
            {
                Pop(&s, &e);
                     //取出栈顶元素来判断与新放入的c是否匹配
                if( !match(e, c) )
                    //如果match执行结果为假,即不匹配
                {
                    Push(&s, e);
                    //原栈顶元素重新入栈
                    Push(&s, c);
                    //将输入的括号字符入栈
                }
            }
        }
        scanf("%c", &c);
    }
    if( !StackLen(s) )
    {
        printf("\nThe parentheses in the input string match exactly \n");
    }
    else
    {
        char p;
        Pop(&s, &p);
        char q;
        if(p=='{'){strcpy(&q,"}");}
        if(p=='}'){strcpy(&q,"{");}
          if(p=='('){strcpy(&q,")");}
         if(p==')'){strcpy(&q,"(");}
        printf("\nThe parentheses in the input string do not exactly match is lack:%c\n",q);
        char w,y;   
        for(Pop(&s, &w);w;Pop(&s, &w)){
          if(w=='{'){strcpy(&y,"}");}
         if(w=='}'){strcpy(&y,"{");}
          if(w=='('){strcpy(&y,")");}
         if(w==')'){strcpy(&y,"(");}
            printf("and:%c\n",y);
            strcpy(&w,"\0");
        }
    }
    return 0;
}

方法三:方法一的简易版但不完整

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

#define STACK 20
#define STACKINCREMENT 10

typedef struct
{
    char *base;         // 栈底指针
    char *top;          // 栈顶指针
    int stackSize;      // 栈大小
} sqStack;

void InitStack(sqStack *s)
{
    s->base = (char *)malloc(STACK * sizeof(char));  // 为栈分配内存
    if (!s->base)
        exit(0);  // 分配失败则退出程序
    s->top = s->base;
    s->stackSize = STACK;
}

void Push(sqStack *s, char e)
{
    if (s->top - s->base >= s->stackSize)
    {
        s->base = (char *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(char));  // 栈满时重新分配内存
        if (!s->base)
            exit(0);
        s->top = s->base + s->stackSize;
        s->stackSize = s->stackSize + STACKINCREMENT;
    }
    *(s->top) = e;   // 将元素压入栈顶
    s->top++;
}

int Pop(sqStack *s, char *e)
{
    if (s->top == s->base)
        return 1;  // 栈空,出栈失败
    *e = *--(s->top);  // 弹出栈顶元素
    return 0;
}
int match(char e, char c)  
{
    if( e=='(' && c==')' )
        return 1;
    if( e=='{' && c=='}' )
        return 1;
    return 0;
}
int StackLen(sqStack s)
{
    return (s.top - s.base);  // 返回栈长度
}

int main()
{
    sqStack s;
    char c, e;
    InitStack(&s);
    printf("Please enter the name of the file: ");
    char filename[100];
    scanf("%s", filename);

    FILE *file = fopen(filename, "r");
    if (!file)
    {
        printf("File not found or cannot be opened.\n");
        return 1;  // 无法打开文件,程序退出
    }
	int n = 0;
    int line_number = 1;
    while ((c = fgetc(file)) != EOF)
    {
        if (c == '\n')
        {
            line_number++;  // 更新行号
            continue;
        }

        if( c=='(' || c==')' || c=='{' || c=='}' )
        {                        // 如果是括号,就进栈
            if( !StackLen(s) )   //如果栈的长度为空,c直接进栈
            {
                Push(&s, c);     //存入c
            }
            else                   //如果c放入时,栈已经不空了,
            {
                Pop(&s, &e);
                     //取出栈顶元素来判断与新放入的c是否匹配
                if( !match(e, c) )
                    //如果match执行结果为假,即不匹配
                {
                    Push(&s, e);
                    //原栈顶元素重新入栈
                    Push(&s, c);
                    //将输入的括号字符入栈
                }
            }
        }
    }
    fclose(file);
 	while (Pop(&s, &e)== 0)
   	 {
    	  printf("Unmatched %c at end of file in line %d\n", e, line_number);  // 输出未匹配的括号错误
    	  n++;
   	 }
	if (n == 0)
    {
        printf("All parentheses in the input file match exactly.\n");  // 输出所有括号匹配正确
    }
    else
    {
        printf("There are unmatched parentheses in the input file.\n");  // 输出存在未匹配括号的错误
    }
    return 0;
}

方法四:双栈进行套用

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

#define MAX_SIZE 100

typedef struct {
char bracket;
int line;
} BracketInfo;

typedef struct {
BracketInfo data[MAX_SIZE];
int top;
} Stack;

void initializeStack(Stack *s) {
s->top = -1;
}

int isEmpty(Stack *s) {
return s->top == -1;
}

void push(Stack *s, char bracket, int line) {
if (s->top == MAX_SIZE - 1) {
printf("Stack overflow\n");
exit(1);
}
s->top++;
s->data[s->top].bracket = bracket;
s->data[s->top].line = line;
}

BracketInfo pop(Stack *s) {
if (isEmpty(s)) {
BracketInfo emptyInfo = {'\0', -1};
return emptyInfo;
}
BracketInfo popped = s->data[s->top];
s->top--;
return popped;
}

int main() {
 char filename[100];
    scanf("%s", filename);
 
    FILE *file = fopen(filename, "r");
    if (!file)
    {
        printf("File not found or cannot be opened.\n");
        return 1;  // 无法打开文件,程序退出
    }

Stack s;
initializeStack(&s);

char lineBuffer[1000];
int lineNum = 0;

while (fgets(lineBuffer, sizeof(lineBuffer), file)) {
lineNum++;

for (int i = 0; lineBuffer[i] != '\0'; i++) {
    if (lineBuffer[i] == '(' || lineBuffer[i] == '{') {
    push(&s, lineBuffer[i], lineNum);
    } 
    else if (lineBuffer[i] == ')'  || lineBuffer[i] == '}') {
    if (isEmpty(&s)) {
   // printf("Unmatched %c at line %d\n", lineBuffer[i], lineNum);
    } else {
    BracketInfo popped = pop(&s);
    if ((popped.bracket == '(' && lineBuffer[i] != ')') ||(popped.bracket == '{' && lineBuffer[i] != '}')) {
    //printf("Mismatched %c at line %d, should be %c\n", lineBuffer[i], lineNum, popped.bracket);
                }
            }
        }
    }
}

while (!isEmpty(&s)) {
BracketInfo popped = pop(&s);
printf("Unmatched %c at line %d\n", popped.bracket, popped.line);
}

fclose(file);
return 0;
}

 方法五:适合相邻括号进行匹配

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

#define STACK 20
#define STACKINCREMENT 10
int line_number = 1,i=0;
typedef struct
{
    char *base;         // 栈底指针
    char *top;          // 栈顶指针
    int stackSize;      // 栈大小
    int a[10000];
} sqStack;

void InitStack(sqStack *s)
{
    s->base = (char *)malloc(STACK * sizeof(char));  // 为栈分配内存
    if (!s->base)
        exit(0);  // 分配失败则退出程序
    s->top = s->base;
    s->stackSize = STACK;
}

void Push(sqStack *s, char e)
{
    if (s->top - s->base >= s->stackSize)
    {
        s->base = (char *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(char));  // 栈满时重新分配内存
        if (!s->base)
            exit(0);
        s->top = s->base + s->stackSize;
        s->stackSize = s->stackSize + STACKINCREMENT;
    }
    *(s->top) = e;   // 将元素压入栈顶
    s->top++;
}

int Pop(sqStack *s, char *e)
{
    if (s->top == s->base)
        return 1;  // 栈空,出栈失败
    *e = *--(s->top);  // 弹出栈顶元素
    return 0;
}
int match(char e, char c)  
{
    if( e=='(' && c==')' )
        return 1;
    if( e=='{' && c=='}' )
        return 1;
    return 0;
}
int StackLen(sqStack s)
{
    return (s.top - s.base);  // 返回栈长度
}

int main()
{
    sqStack s;
    char c, e;
    InitStack(&s);
    printf("Please enter the name of the file: ");
    char filename[100];
    scanf("%s", filename);

    FILE *file = fopen(filename, "r");
    if (!file)
    {
        printf("File not found or cannot be opened.\n");
        return 1;  // 无法打开文件,程序退出
    }
	int n = 0;
    while ((c = fgetc(file)) != EOF)
    {
        if(c=='/'){
            c=fgetc(file);
            if(c=='*'){
            do{c = fgetc(file);}while(c!='*');
            }
        }
        if (c == '\n')
        {
            line_number++;  // 更新行号
            continue;
        }

        if( c=='(' || c==')' || c=='{' || c=='}' )
        {                        // 如果是括号,就进栈
            if( !StackLen(s) )   //如果栈的长度为空,c直接进栈
            {
                Push(&s, c); 
                s.a[i++]=line_number;    //存入c  
            }
            else                   //如果c放入时,栈已经不空了,
            {
                Pop(&s, &e);
              
                     //取出栈顶元素来判断与新放入的c是否匹配
                if( !match(e, c) )
                    //如果match执行结果为假,即不匹配
                {
                    Push(&s, e);
                    //原栈顶元素重新入栈
                    Push(&s, c);
                     s.a[i++]=line_number;
                    //将输入的括号字符入栈
                } 
                if(match(e,c)) 
                {
                    i--;
                }  
            }
        }
    }
    fclose(file);
 	for (Pop(&s, &e),i=i-1;e;Pop(&s, &e),i--)
   	 {
    	  printf("Unmatched %c at end of file in line %d\n", e, s.a[i]);  // 输出未匹配的括号错误
    	  n++;
          strcpy(&e,"\0");
   	 }
	if (n == 0)
    {
        printf("All parentheses in the input file match exactly.\n");  // 输出所有括号匹配正确
    }
    else
    {
        printf("There are unmatched parentheses in the input file.\n");  // 输出存在未匹配括号的错误
    }
    return 0;
}

方法六: 底层代码不全可以查看思路

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

#define STACK 20
#define STACKINCREMENT 10
int line_number = 1,i=0,j=0;
typedef struct
{
    char *base;         // 栈底指针
    char *top;          // 栈顶指针
    int stackSize;      // 栈大小
    int a[10000];
} sqStack;

void InitStack(sqStack *s)
{
    s->base = (char *)malloc(STACK * sizeof(char));  // 为栈分配内存
    if (!s->base)
        exit(0);  // 分配失败则退出程序
    s->top = s->base;
    s->stackSize = STACK;
}

void Push(sqStack *s, char e)
{
    if (s->top - s->base >= s->stackSize)
    {
        s->base = (char *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(char));  // 栈满时重新分配内存
        if (!s->base)
            exit(0);
        s->top = s->base + s->stackSize;
        s->stackSize = s->stackSize + STACKINCREMENT;
    }
    *(s->top) = e;   // 将元素压入栈顶
    s->top++;
}

int Pop(sqStack *s, char *e)
{
    if (s->top == s->base)
        return 1;  // 栈空,出栈失败
    *e = *--(s->top);  // 弹出栈顶元素
    return 0;
}
int match(char e, char c)  
{
    if( e=='(' && c==')' )
        return 1;
    if( e=='{' && c=='}' )
        return 1;
    return 0;
}
int StackLen(sqStack s)
{
    return (s.top - s.base);  // 返回栈长度
}

int main()
{
    sqStack s;
    sqStack w;
    char c, e;
    InitStack(&s);
    InitStack(&w);
    printf("Please enter the name of the file: ");
    char filename[100];
    scanf("%s", filename);

    FILE *file = fopen(filename, "r");
    if (!file)
    {
        printf("File not found or cannot be opened.\n");
        return 1;  // 无法打开文件,程序退出
    }
	int n = 0;
    while ((c = fgetc(file)) != EOF)
    {
        if(c=='/'){
            c=fgetc(file);
            if(c=='*'){
            do{c = fgetc(file);}while(c!='*');
            }
        }
        if (c == '\n')
        {
            line_number++;  // 更新行号
            continue;
        }

        if( c=='(' || c==')' )
        {                        // 如果是括号,就进栈
            if( !StackLen(s) )   //如果栈的长度为空,c直接进栈
            {
                Push(&s, c); 
                s.a[i++]=line_number;    //存入c  
            }
            else                   //如果c放入时,栈已经不空了,
            {
                Pop(&s, &e);
              
                     //取出栈顶元素来判断与新放入的c是否匹配
                if( !match(e, c) )
                    //如果match执行结果为假,即不匹配
                {
                    Push(&s, e);
                    //原栈顶元素重新入栈
                    Push(&s, c);
                     s.a[i++]=line_number;
                    //将输入的括号字符入栈
                } 
                if(match(e,c)) 
                {
                    i--;
                }  
            }
        }
        if( c=='{' || c=='}' )
        {                        // 如果是括号,就进栈
            if( !StackLen(w) )   //如果栈的长度为空,c直接进栈
            {
                Push(&w, c); 
                w.a[j++]=line_number;    //存入c  
            }
            else                   //如果c放入时,栈已经不空了,
            {
                Pop(&w, &e);
              
                     //取出栈顶元素来判断与新放入的c是否匹配
                if( !match(e, c) )
                    //如果match执行结果为假,即不匹配
                {
                    Push(&w, e);
                    //原栈顶元素重新入栈
                    Push(&w, c);
                     w.a[j++]=line_number;
                    //将输入的括号字符入栈
                } 
                if(match(e,c)) 
                {
                    j--;
                }  
            }
        }
    }
    fclose(file);
 	for (Pop(&s, &e),i=i-1;e;Pop(&s, &e),i--)
   	 {
    	  printf("Unmatched %c at end of file in line %d\n", e, s.a[i]);  // 输出未匹配的括号错误
    	  n++;
          strcpy(&e,"\0");
   	 }
        for (Pop(&w, &e),j=j-1;e;Pop(&w, &e),j--)
   	 {
    	  printf("Unmatched %c at end of file in line %d\n", e, w.a[j]);  // 输出未匹配的括号错误
    	  n++;
          strcpy(&e,"\0");
   	 }
	if (n == 0)
    {
        printf("All parentheses in the input file match exactly.\n");  // 输出所有括号匹配正确
    }
    else
    {
        printf("There are unmatched parentheses in the input file.\n");  // 输出存在未匹配括号的错误
    }
    return 0;
}

运行结果 :封面

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
以下是一个简单的 Python 程序用于对输入的 C 源程序进行括号匹配检查,并将结果输出文件: ```python def check_parentheses(file_in, file_out): with open(file_in, 'r') as f_in, open(file_out, 'w') as f_out: code = f_in.read().strip() stack = [] error = False for i, char in enumerate(code): if char in '({[': stack.append((char, i)) elif char in ')}]': if not stack: f_out.write(f"Error: Extra closing bracket at position {i}\n") error = True else: last_bracket, pos = stack.pop() if (last_bracket == '(' and char != ')') or (last_bracket == '{' and char != '}') or (last_bracket == '[' and char != ']'): f_out.write(f"Error: Mismatched brackets at positions {pos} and {i}\n") error = True if not error and stack: f_out.write("Error: Extra opening bracket(s) at positions ") for bracket, pos in stack: f_out.write(f"{pos}, ") f_out.write("\n") elif not error: f_out.write("All brackets are matched and nested correctly.\n") check_parentheses('input.c', 'output.txt') ``` 这个程序首先打开输入文件,读取其的代码。然后,使用一个栈来跟踪打开的括号,当遇到一个括号时,将其压入栈;当遇到一个括号时,将其弹出栈,并检查它是否与栈顶的左括号匹配。如果有任何错误,则将错误信息写入输出文件并将错误标志设置为 True。最后,如果没有错误,但栈仍然有未配对的左括号,则将这些括号视为错误,并将其位置写入输出文件。 注意,这个程序检查括号的匹配和嵌套,而没有检查其他语法错误。如果需要完整的 C 语言语法分析器,请使用专业的工具。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值