CFormat - C/C++代码格式化工具 [ In C++ ]

FutureCode posted @ Mon, 01 Feb 2010 05:14:03 +0800 in Chapter 1 - Applications , 2689 readers

Description

   相比颜色上的缺陷,那些经过百度、QQ空间等空格简并后的源代码则更让人头晕——尤其是在阅读结构复杂的程序时。在迁入is-programmer后前者可以说已经完全解决,而为了解决后者,我们开发了应用程序CFormat。

    与往常一样,我们采用的是逐行处理技术,可以自动识别用"{}"构成的循环结构与条件结构,并进行分层排版。该程序可以准确地识别程序中的字符串,也可以有效地添加空白字符以方便阅读。需要注意的是,由于注释的含义与作用可以有很多种,所以输出文件中将不会包含输入文件中的注释,如有需要请自行添加。而且该程序只能识别C/C++语言,在遇到以"#"开头的预处理器语句,程序将报错并停止运行,所以在输入文件中如有预处理器语句,请将其删除。如果该程序不能生成正确的格式化代码,请检查:1.输入文件部分是否能通过编译 2.输入文件是否将完整的一行分成了两行。如仍然存在问题,请单击上方的"QQ me!"联系我。

    输入文件名称:  CFormat.in

    输出文件名称:  CFormat.out

Source File

 

#include <fstream>
#include <cstring>

using namespace std;
bool bSpace = true;
bool bComment = false;
int nString = 0;
int nBlock = 0;
int nRealBlock = 0;
int nBlockInfo[100]; // 0 - inner   1 - real block
int nBracket = 0;
int nQuote = 0;      // 0 - none   1 - '   2 - "
char cQuote[3] = {0, '\'', '\"'};
bool bBacklash = false;
const char *strKey[] = {".","->","::","++","--","[]","[","&&","||","<<",">>","==","<=",">=","!=","+=","-=","*=","/=","%=","<<=",">>=","&=","|=","^="};
const int nKey = 25;
int IsIdentifier[130] = {0,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,
1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,
0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0};

int ProcessLine(ifstream &fIn, ofstream &fOut)
{
	int i, j;
	char strIn[1030];
	char buffer[1030];
	if(fIn.eof() == 1)return 0;
	fIn.getline(strIn, 1024);
	for(i = j = 0; i < strlen(strIn); i++)if(strIn[i] != '\t')buffer[j++] = strIn[i];
	buffer[j] = ' ';
	buffer[j + 1] = 0;
	for(i = 0; i < strlen(buffer); i++)
	{
		if(bComment == true)
		{
			char *pEnd = strstr(&buffer[i], "*/");
			if(pEnd == NULL)return 1;
			else
			{
				i = pEnd - buffer + 1;
				bComment = false;
			}
			continue;
		}
		if(nString != 0)
		{
			char *pEnd = strchr(&buffer[i], cQuote[nString]);
			if(pEnd != NULL)
			{
				j = 1;
				while(j == 1)
				{
					for(j = 1; pEnd[-j] == '\\'; j++);
					if(j % 2 == 0)
					{
						j = 1;
						pEnd = strchr(pEnd + 1, cQuote[nString]);
					}
					else j = 0;
				}
				if(pEnd == NULL)
				{
					fOut << &buffer[i];
					return 1;
				}
			}
			else
			{
				fOut << &buffer[i];
				return 1;
			}
			for(; i <= pEnd - buffer; i++)fOut << buffer[i];
			fOut << ' ';
			i--;
			nString = 0;
			continue;
		}
		if(bSpace == false)
		{
			if(buffer[i] == ',')
			{
				fOut << ", ";
				bSpace = true;
			}
			else if(buffer[i] == '(')
			{
				fOut << "( ";
				nBracket++;
				bSpace = true;
			}
			else if(buffer[i] < 0)
			{
				fOut << endl;
				fOut << "Format terminated : unexpected character ( ASCII < 0 ) found , will it compile ?";
				return 0;
			}
			else if(IsIdentifier[buffer[i]] == 1)fOut << buffer[i];
			else 
			{
				fOut << ' ';
				bSpace = true;
				i--;
			}
			continue;
		}
		if(buffer[i] == ' ')continue;
		if(buffer[i] == '{')
		{
			if(nBracket != 0 || (i >= 1 && buffer[i - 1] == '=') || (i >= 2 && buffer[i - 1] == ' ' && buffer[i - 2] == '='))
			{
				fOut << "{ ";
				nBlockInfo[nBlock++] = 0;
			}
			else
			{
				fOut << endl;
				for(j = 0; j < nRealBlock; j++)fOut << "    ";
				fOut << '{' << endl;
				nRealBlock++;
				for(j = 0; j < nRealBlock; j++)fOut << "    ";
				nBlockInfo[nBlock++] = 1;
			}
			continue;
		}
		if(buffer[i] == '}')
		{
			nBlock--;
			if(nBlock < 0)
			{
				fOut << endl;
				fOut << "Format terminated : '}' underflowed" << endl;
				return 0;
			}
			if(nBlockInfo[nBlock] == 1)
			{
				nRealBlock--;
				for(j = i - 1; j >= 0; j--)if(buffer[j] != ' ')break;
				if(j == -1 || buffer[j] == ';')
				{
					fOut.seekp(-4, ios::cur);
					fOut << '}' << endl;
					for(j = 0; j < nRealBlock; j++)fOut << "    ";
				}
				else
				{
					fOut << endl;
					for(j = 0; j < nRealBlock; j++)fOut << "    ";
					fOut << '}' << endl;
					for(j = 0; j < nRealBlock; j++)fOut << "    ";
				}
				for(j = i + 1; j < strlen(buffer); j++)if(buffer[j] == ';')break;
				if(j != strlen(buffer))
				{
					fOut.seekp(-1, ios::cur);
					fOut << ';' << endl;
					i = j;
				}
				if(nBlock == 0)fOut << endl;
			}
			else fOut << "} ";
			continue;
		}
		if(buffer[i] == '(')
		{
			for(j = i - 1; j >= 0; j--)if(buffer[j] != ' ')break;
			if(j != -1 && buffer[j] != ';' && IsIdentifier[buffer[j]] == 1)fOut.seekp(-1, ios::cur);
			nBracket++;
			fOut << "( ";
			continue;
		}
		if(buffer[i] == ')')
		{
			nBracket--;
			if(nBracket < 0)
			{
				fOut << endl;
				fOut << "Format terminated : ')' underflowed" << endl;
				return 0;
			}
			fOut << ") ";
			continue;
		}
		if(buffer[i] == '-' && buffer[i + 1] == '>')
		{
			for(j = i - 1; j >= 0; j--)if(buffer[j] != ' ')break;
			if(j != -1)fOut.seekp(-1, ios::cur);
			fOut << "->";
			continue;
		}
		if(buffer[i] == '.')
		{
			for(j = i - 1; j >= 0; j--)if(buffer[j] != ' ')break;
			if(j != -1)fOut.seekp(-1, ios::cur);
			fOut << '.';
			continue;
		}
		if(buffer[i] == ';')
		{
			for(j = i - 1; j >= 0; j--)if(buffer[j] != ' ')break;
			if(j != -1)fOut.seekp(-1, ios::cur);
			if(nBracket != 0)fOut << "; ";
			else
			{
				fOut << ';' << endl;
				for(j = 0; j < nRealBlock; j++)fOut << "    ";
			}
			continue;
		}
		if(buffer[i] == ',')
		{
			for(j = i - 1; j >= 0; j--)if(buffer[j] != ' ')break;
			if(j != -1)fOut.seekp(-1, ios::cur);
			fOut << ", ";
			continue;
		}
		if(buffer[i] == '#')
		{
			fOut << endl;
			fOut << "Format terminated : Preprocessor word '#' found" << endl;
			return 0;
		}
		if(buffer[i] == '/' && buffer[i + 1] == '/')return 1;
		if(buffer[i] == '/' && buffer[i + 1] == '*')
		{
			bComment = true;
			i++;
			continue;
		}
		if(buffer[i] == '\'')
		{
			fOut << '\'';
			nString = 1;
			continue;
		}
		if(buffer[i] == '\"')
		{
			fOut << '\"';
			nString = 2;
			continue;
		}
		for(j = 0; j < nKey; j++)
		{
			if(strncmp(&buffer[i], strKey[j], strlen(strKey[j])) == 0)
			{
				if(j < 7)
				{
					int k;
					for(k = i - 1; k >= 0; k--)if(buffer[k] != ' ')break;
					if(k != -1 && buffer[k] != ';')fOut.seekp(-1, ios::cur);
				}
				fOut << strKey[j];
				if(j >= 3)fOut << ' ';
				i += strlen(strKey[j]) - 1;
				break;
			}
		}
		if(j < nKey)continue;
		if(buffer[i] < 0)
		{
			fOut << endl;
			fOut << "Format terminated : unexpected character ( ASCII < 0 ) found , will it compile ?";
			return 0;
		}
		fOut << buffer[i];
		if(IsIdentifier[buffer[i]] == 0)fOut << ' ';
		else bSpace = false;
	}
	return 1;
}

int main()
{
	ifstream fIn;
	ofstream fOut;
	fIn.open("CFormat.in");
	fOut.open("CFormat.out");
	if(fIn.is_open() == 0)
	{
		fOut << "Format terminated : No input file detected" << endl;
		return 0;
	}
	while(ProcessLine(fIn, fOut) == 1);
	return 0;
}

 

Avatar_small
Harold said:
Wed, 27 Jan 2021 21:37:05 +0800

This article can be a piece of very good knowledge for CS students like me. Vegan Recipes For Muscle Building Actually, this is good for learning. Thanks for sharing this data. It is really educational. Articles like this help me to improve my learning of C++.

Avatar_small
John Hona said:
Fri, 16 Jul 2021 15:40:46 +0800

Over the years Akshaya hospital has blossomed into a comprehensive care centre for Best Hospital for Myomectomy in Kochi women of all ages providing expert care in the fields of pregnancy, infertility and laparoscopic surgeries.

Avatar_small
Glendich said:
Sat, 17 Jul 2021 16:55:06 +0800

Vijayalakshmi Medical Centre has completed 10 years of success in the field of gynaecology and infertility. We are the best among the first few comprehensive dedicated infertility hospitals in Asia. ivf treatment in kochi Our expertise in the field of infertility has made us come forward with an exclusive department in our hospital. We are delighted to present our infertility department ‘Babycart’.

Avatar_small
AAA said:
Sun, 02 Jan 2022 05:17:58 +0800

Awsome submit as well as right to the idea. I am not sure if this is actually the best place to inquire about however would you individuals have any thoughts on where you’ll get a few ghost writers? Thx 메이저사이트

Avatar_small
AAA said:
Thu, 17 Feb 2022 04:01:17 +0800

Thanks for sharing this first-class article. Very inspiring! (as always, btw) 메이저사이트

Avatar_small
NCERT Urdu Question said:
Thu, 29 Sep 2022 19:54:45 +0800

Every student of Secondary education can download NCERT STD-10 Urdu Sample Paper 2023 with sample answers to gain high score by knowing the new exam scheme or question paper style for all exams such as SA1, SA2, FA1, FA2, FA3, FA4 and Assignments held under Term-1 & Term-2 of the course. The NCERT have introduced subject wide study & learning material for all regional students of the country. NCERT Urdu Question Paper Class 10 Every student of Secondary education can download NCERT STD-10 Urdu Sample Paper 2023 with sample answers to gain high score by knowing the new exam scheme or question paper style for all exams such as SA1, SA2, FA1, FA2, FA3, FA4.

Avatar_small
meidir said:
Tue, 04 Oct 2022 06:12:53 +0800

I bookmared your site a couple of days ago coz your blog impresses me . adobe


Login *


loading captcha image...
(type the code from the image)
or Ctrl+Enter