/*
C++风格的注释(//) 在某些C编译器里通不过,
写个程序读入一个文件,并存为另一个文件,
将注释全改为C风格的哦!
注意有些特殊情况。
*/
这题目是偶想出来的,感觉挺有意思,大家试试啊~
//我的程序又很长,不如你的精悍,但还没发现BUG
//CharStack.h我就不帖出来了,占地方
//晕,怎么在这里缩进这么难看。。。。
/******************************************
*
* Copyright by NJU_SE_SirX
* 2006.2.3
******************************************/
//本程序将C++风格的注释(//)转换为C风格(/* */)的注释,并将新文件保存为原文件名+_NEW
//只转换纯文本文档
//考虑到了几种特殊情况:
// 1.cout<<"....\"...\"..."; //....."...."......."........ 用栈解决
// 2./*....
// ...//...
// ...*/ 判断是否在注释中
//至于如://..//..//////...因为是直接查找第一个出现的 // ,所以没问题
#include "CharStack.h"
#include <iostream>
#include <string>
#include <fstream>
#include <conio.h> //getch()
using namespace std;
string getTrueFile(); //确保要修改的文件存在
class File {
const string newTag;
string fName;
ifstream inFile;
ofstream outFile;
bool inComment;
const string outName() const; //得到新文件名称
void proLine(const string &line); //处理1行
void setLine(const string &line,int index); //输出新行
public:
File(const string &name,const string &tag="_NEW");
~File();
void process(); //处理文件
void print(bool cls=true) const; //输出新文件
};
File::File(const string &name,const string &tag) :fName(name),newTag(tag),inComment(false) {
inFile.open(fName.c_str());
outFile.open(outName().c_str());
}
File::~File() {
cout<<"■";
system("pause");
}
const string File::outName() const {
int partion=-1;
for(int i=fName.length()-1;i>0;i--) {
if('.'==fName[i]) {
partion=i;
break;
}
}
if(-1==partion)
return fName.substr(0,fName.length()) + newTag;
//else
return fName.substr(0,partion) + newTag + fName.substr(partion,fName.length()-partion+1);
}
void File::proLine(const string &line) {
CharStack stack; //用来处理 "
for(int i=0;i<line.length();i++) {
//特殊情况:" 与 // 包含问题
if('"'==line[i] || '/'==line[i]) {
//1. "
if('"'==line[i]) {
if(i>0 && '\\'==line[i-1])
continue; //排除 \"
//else
if(stack.isEmpty())
stack.push('"');
else stack.pop();
}
//2. /
else if(stack.isEmpty()) {
if(i>0 && '*'==line[i-1]) {
inComment=false;
continue;
}
if(i<line.length()-1) {
if('*'==line[i+1])
inComment=true;
if('/'==line[i+1]) {
setLine(line,i);
return;
}
}
}
}
}
outFile<<line<<endl;
}
void File::setLine(const string &line,int index) {
string newLine;
if(!inComment)
newLine=line.substr(0,index) + "/*" + (((index+2)==line.length())?" ":line.substr(index+2,line.length()-index-2)) + "*/";
else newLine=line.substr(0,index) + "\"//\"" + (((index+2)==line.length())?" ":line.substr(index+2,line.length()-index-2));
outFile<<newLine<<endl;
}
void File::process() {
string line;
while(getline(inFile,line))
proLine(line);
cout<<"■转换成功,新文件已存为【"+outName()+"】。"<<endl;
}
void File::print(bool cls) const {
if(cls)
system("cls");
cout<<"【"+outName()+"】"<<endl;
cout<<"--------------------------------------------------------------------------------";
string line;
ifstream in(outName().c_str());
while(getline(in,line))
cout<<line<<endl;
cout<<"--------------------------------------------------------------------------------";
cout<<"【End】"<<endl;
}
string getTrueFile() { //这个函数真难!用了大概半小时解决!主要是VC6中的getline(...)“双回车”问题,绕开了
ifstream *inFile;
char fName[30]={0};
while(true) {
cout<<"■请输入源文件名称(含扩展名,如.cpp) :";
cin.getline(fName,20,'\n'); //trouble here!用 ifstream* 解决
if(0==fName[0])
continue;
inFile=new ifstream(fName);
if(*inFile)
break; //打开文件成功
//else
delete inFile;
cout<<"└文件【"<<fName<<"】不存在,"<<"请重新输入。\n"<<endl;
for(int i=0;i<30;i++)
fName[i]=0;
}
return fName;
}
int main() {
cout<<"--------------------------------------------------------------------------------"<<endl;
cout<<" 〓〓〓 C++注释转换器 v1.0版 〓〓〓\n"<<endl;
cout<<"--------------------------------------------------------------------------------"<<endl;
File f(getTrueFile());
f.process();
char sign;
while(true) {
cout<<"└需要查看吗?(Y/N) : ";
sign=getch();
cout<<endl;
if('Y'==sign || 'y'==sign) {
f.print(true);
break;
}
else if('N'==sign || 'n'==sign)
break;
cout<<" 请正确输入(Y/N)!"<<endl;
}
return 0;
}
[此贴子已经被作者于2006-2-4 17:11:10编辑过]