1. 程式人生 > >C程式括號匹配檢查

C程式括號匹配檢查

【問題描述】

編寫一程式檢查C源程式檔案中{}、()等括號是否匹配,並輸出第一個檢測到的不匹配的括號及所對應括號所在的行號(程式中只有一個括號不匹配)。

注意:

1.     除了括號可能不匹配外,輸入的C源程式無其它語法錯誤;

2.     字元常量、字串常量及註釋中括號不應被處理,註釋包括單行註釋//和多行/* */註釋

3. 字元和字串常量中不包含特殊的轉義字元(\',\")

5. 程式中出現有意義括號的個數不超過200個

不匹配判斷規則:

1. 當遇到一個不匹配的右括號(')'或'}')時,輸出該右括號及所在行號;

2. 當程式處理完畢時,還存在不匹配的左括號時,輸出該左括號及所在行號。

【輸入形式】

開啟當前目錄下檔案example.c,查體其括號是否匹配。

【輸出形式】

若存在括號不匹配時,應輸出首先能判斷出現不匹配的括號及其所在的行號。當出現括號不匹配時,按下面要求輸出相關資訊:

without maching <x> at line <n>

其中<x>為‘{’, ‘}’, ‘(’, ‘)’等符號,<n>為該符號所在的行號。

若整個程式括號匹配,則按下面所示順序輸出括號匹配情況,中間沒有空格。

(){(()){}}

【樣例輸入1】

若當前目錄下輸入檔案example.c中內容如下:

#include<stdio.h>

int main(){

printf("{ hello world }\n"); // }

)

【樣例輸出1】

without maching ')' at line 4

【樣例輸入2】

若當前目錄下輸入檔案example.c中內容如下:

#include<stdio.h>

int main(){

printf("{ hello world }d\n"); /* }*/

【樣例輸出2】

without maching '{' at line 2

【樣例輸入3】

若當前目錄下輸入檔案example.c中內容如下:

#include<stdio.h>

int main(){

printf("{ hello world }d\n"); /* }*/

}

【樣例輸出3】

(){()}


【樣例說明】

樣例1:在註釋部分和字串中的括號不考慮,在將程式處理之後得到的括號序列是(){()),遇到右括號時與最近的左括號匹配,發現最後一個小括號和大括號不匹配。

樣例2:處理之後的括號序列是(){(),在最後缺少了右大括號,那麼應該輸出與之相對應的左括號不匹配。

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

void ERROR(char b, int l, int *e)
{
	(*e)++;
	printf("without maching '%c' at line %d\n",b,l);
}

int main()
{
	FILE *fin;
	int tmp;
	int linenum[1000];
	char bracket_stack[500], bracket_w_stack[1000];
	int  iter_bstack = -1, iter_w_bstack = -1, error = 0, line = 1;
	fin = fopen("example.c", "r");
	if (fin == NULL) exit(1);
	for (;;)
	{
		tmp = fgetc(fin);
		if (tmp == EOF) break;
		else if (tmp == '\n') line++;
		else if (tmp == '"')
		{
			for (;;)
			{
				tmp = fgetc(fin);
				if(tmp=='\\') tmp = fgetc(fin);
				else if (tmp == '"') break;
			}
		}
		else if (tmp == '\'')
		{
			for (;;)
			{
				tmp = fgetc(fin);
				if (tmp == '\\') tmp = fgetc(fin);
				else if (tmp == '\'') break;
			}
		}
		else if (tmp == '/')
		{
			tmp = fgetc(fin);
			if (tmp == '/') 
			{// single-line comment 
				while ((tmp = fgetc(fin)) != '\n'); 
				line++;
			} 
			else if (tmp == '*')
			{// multi-line comment
				int flag = 0;
				tmp = fgetc(fin);
				if (tmp == '\n') line++;
				for (;;)
				{
					if (flag) break;
					while (tmp != '*') 
					{ 
						tmp = fgetc(fin); 
						if (tmp == '\n') line++;
					}
					tmp = fgetc(fin);
					if (tmp == '\n') line++;
					if (tmp == '/') flag = 1;
				}
			}
			else if (tmp == '(')
			{
				bracket_stack[++iter_bstack] = tmp;
				bracket_w_stack[++iter_w_bstack] = tmp;
				linenum[iter_bstack] = line;
			}
		}
		else if (tmp == '(' || tmp == '{')
		{
			bracket_stack[++iter_bstack] = tmp;
			bracket_w_stack[++iter_w_bstack] = tmp;
			linenum[iter_bstack] = line;
		}
		else if (tmp == ')')
		{
			bracket_w_stack[++iter_w_bstack] = tmp;
			linenum[iter_bstack] = line;
			int leap = 0;
			while (leap <= iter_bstack && bracket_stack[iter_bstack - leap] != '(') leap++;
			if (iter_bstack<0 || leap) ERROR(tmp, line, &error);
			if (leap <= iter_bstack)
			{
				int i;
				for (i = iter_bstack - leap; i < iter_bstack; i++)
				{
					bracket_stack[i] = bracket_stack[i + 1];
					linenum[i] = linenum[i + 1];
				}
				iter_bstack--;
			}
		}
		else if (tmp == '}')
		{
			bracket_w_stack[++iter_w_bstack] = tmp;
			linenum[iter_bstack] = line;
			int leap = 0;
			while (leap <= iter_bstack && bracket_stack[iter_bstack - leap] != '{') leap++;
			if (iter_bstack<0 || leap) ERROR(tmp, line, &error);
			if (leap <= iter_bstack)
			{
				int i;
				for (i = iter_bstack - leap; i < iter_bstack; i++)
				{
					bracket_stack[i] = bracket_stack[i + 1];
					linenum[i] = linenum[i + 1];
				}
				iter_bstack--;
			}
		}
		else continue;
	}
	bracket_w_stack[++iter_w_bstack] = '\0';
	while (!error && iter_bstack >= 0)
	{
		ERROR(bracket_stack[iter_bstack], linenum[iter_bstack], &error);
		iter_bstack--;
	}
	if(!error) printf("%s", bracket_w_stack);
	fclose(fin);
	return 0;
}