Description
相比颜色上的缺陷,那些经过百度、QQ空间等空格简并后的源代码则更让人头晕——尤其是在阅读结构复杂的程序时。在迁入is-programmer后前者可以说已经完全解决,而为了解决后者,我们开发了应用程序CFormat。
与往常一样,我们采用的是逐行处理技术,可以自动识别用"{}"构成的循环结构与条件结构,并进行分层排版。该程序可以准确地识别程序中的字符串,也可以有效地添加空白字符以方便阅读。需要注意的是,由于注释的含义与作用可以有很多种,所以输出文件中将不会包含输入文件中的注释,如有需要请自行添加。而且该程序只能识别C/C++语言,在遇到以"#"开头的预处理器语句,程序将报错并停止运行,所以在输入文件中如有预处理器语句,请将其删除。如果该程序不能生成正确的格式化代码,请检查:1.输入文件部分是否能通过编译 2.输入文件是否将完整的一行分成了两行。如仍然存在问题,请单击上方的"QQ me!"联系我。
输入文件名称: CFormat.in
输出文件名称: CFormat.out
Source File
#include
#include
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;
}