先打个广告: http://www.cnblogs.com/aiasted 我的博客请看题目: 大家都知道 C# 使用 // 或 /* */ 作为注释 提问,怎样才能删除一个cs文件中所有的,各种形式的注释 特别提示: 当二种注释一起出现时的处理,二种注释同时出现,那一种有效自己开个VS试吧
结果参照:
要求有完整的代码,界面就不需要了,不过至少要有打开和保存文件吧
使用文件类来操作,输入原文件,输出新文件 如果您从来没写过此类算法,那么测试将有效,你可以参照以下标准评分: 10分钟内写完 你一定是个绝顶高手,而且打字速度很快 30分钟内写完 算是个高手吧,至少算法基础比较熟悉 60分钟内写完 一般吧你 XXX小时能够写完 你可以算是个程序员吧 不会写??? 你别搞程序了,智商不够高 代码就不用贴出来了,影响其它人,自己凭着良心评分吧 最后,此方法大约共 16 行代码可搞定 我用VC,边看动画边写,用了1个小时,我是个白痴..555...
结果参照:
要求有完整的代码,界面就不需要了,不过至少要有打开和保存文件吧
使用文件类来操作,输入原文件,输出新文件 如果您从来没写过此类算法,那么测试将有效,你可以参照以下标准评分: 10分钟内写完 你一定是个绝顶高手,而且打字速度很快 30分钟内写完 算是个高手吧,至少算法基础比较熟悉 60分钟内写完 一般吧你 XXX小时能够写完 你可以算是个程序员吧 不会写??? 你别搞程序了,智商不够高 代码就不用贴出来了,影响其它人,自己凭着良心评分吧 最后,此方法大约共 16 行代码可搞定 我用VC,边看动画边写,用了1个小时,我是个白痴..555...
要不了16行代码啊.
写的紧凑写,一行就ok啊.
你的方法是可以的但C#里还有
/*
...
...
...
*/
这样的形式,不如动动手,写一写,看看能匹配上那一条
1:第一行肯定删,第二行删不删?应该在程序中提供选项,是否允许嵌套
// /*
*/ 2:第一行算不算一对完整的注释?
/*/
*/3:我曾经这样用过:在第一行前加一个“/”(只有这一步操作),一对注释全都失效,但又没有语法错误,楼上几位的程序能分析?
/*
MessageBox.Show("...");
/*/4:。这些情况考虑全了,估计没有半个小时完不成,程序还没开始呢
*/段注释/*
MessageBox.Show("...");
/*/也是段注释VC环境是这样的,C#没试
{
if(!File.Exists(FileName))
return ;
System.IO.FileStream sm=File.OpenWrite(FileName); byte[] buf = new byte[2];
int b=sm.Read(buf,0,2);
bool IsString=false;
long offset=0;
while(b!=-1)
{
if(buf[0]=='\\'&&buf[1]=='\"')
IsString=!ISstring;
if(buf[0]=='\"'||bu[1]=='\"')
IsString=!ISstring;
if(!(buf[0] == '\r' && buf[1] == '\n'))
{
}
if(buf[0]=='\\'&&buf[1]=='*'&&!IsString)
{
//删除操作
sm.Close();
Delete(FileName);
}
if(buf[0]=='/'&&buf[1]=='/'&&!IsString)
{
//删除操作
sm.Close();
Delete(FileName);
}
offset+=i;
b=sm.Read(2,0,2);
}
}
这是个好题目,功夫不到家还真难编出来
我用了两个小时到现在还不敢保证没错程序员最需要的是严谨的思维,令我感到遗憾的是楼上这十几个回复中竟然没有一个人考虑全面
这个题目绝对是16行代码搞不定的,我敢保证楼主也没考虑全面只做上面这一点提示,大家自己想一想吧
我的程序先不公开,不过单元测试写好了,谁认为自己考虑全面了把程序贴上来,我给你测试,并告诉你结果。为了方便单元测试,统一一下接口:
只写一个方法,原形为public static string RemoveComment(string content);
content就是文件的内容,包括回车等等,是用streamReader.ReadToEnd()得到的,返回去掉注释以后的文件内容。如果读文件自己另写方法,我只测试这一个函数。
例如:
我调用
string content = @"
class abc
{
public abc()
{
int a;//This is a comment.
//This is a comment too.
}
}
";
string result = RemoveComment(content);
result的值应该是
@"
class abc
{
public abc()
{
int a;
}
}
";不考虑通不过编译的语法错误,但应能处理所有符合C#语法的程序
MessageBox.Show("...");
//*/也是段注释
longqiaoman(龙桥人) ,你说的碰到//就把事先删除是不对的!!因为可能//会写在有用代码的后面,例如:int n=0; //n.......
还有在判断"//"和"/*"与"*/"时,还要判断这些符号是否在字符串内,因为在程序中!如果我写了以下的代码,string st="abc//qwer";或
string s1="/*asdfg";
string s2="asdfg*/";
这可不能随便删除的!!
要考虑的情况还有很多!!
C#中还////的定义字符!等等!16行代码怎么能搞得掂!
fancyf说的不错:这个题目绝对是16行代码搞不定的,我敢保证楼主也没考虑全面。
各位,动手写代码之前先进行一下需求分析还行啊。楼主以为一个项目就用到了C#的所有特性么。
把你的程序改成result = RemoveComment(string content);的形式发出来给我
我给你测试一下
觉得这样的代码写出来必定很复杂,以上说的//和 /* */就已经够麻烦了.而且还要判断是正常的注释,还是字符串,呵呵!还有类似"/*/**/"这样的东西,而且C#的注释比C++强大多了,#region,#endregion算不算注释啊?楼主所说的,是"所有的,各种形式的注释".如果这些楼主16行就能搞定的话,我真的不搞程序了.
* 传统风格的注释
*/
//dfkgdkfgjdflk
/*
//75645645
*/456565 //
5656745 ///*455476
45864958645 // */";
string p8 = @"/\*(.|\n)*?\*/";
string p1 = @"//(.)*$";
t8 = Regex.Replace(t8,p1,"\r\n");
string r8 = Regex.Replace(t8, p8, "" );
#region #endregion与程序功能无关,也是注释,也该去掉
首先当然是判断// /* */这几个字符是不是在字符串里面!!(单是判断这个就不知要多少个16行了!)
以我所想判断这些字符是否在字符串内有很多种情况,
string st="aaaa\"sss//aa"; 这种情况在字符串内
string st="aaaa"; //aaaa
string st="aaaa\"//aa";
string st=@"aaaa\"; //aa 这种情况不在字符串内判断是否在字符内主要情况有两种,就是字符串前面是否有@,主要判断第一个"前面的字符是不是@就行了!
判断// /* */ 是在字符串内还是" 在这些字符里,这里需要很多的判断!!暂时写到这里,我要去开会了!等一下接着!
* 传统风格的注释
*/
//dfkgdkfgjdflk
/*
//75645645
*/456565 //
5656745 ///*455476
45864958645 // */";
string p8 = @"/\*(.|\n)*?\*/";
string p1 = @"//(.)*$";
t8 = Regex.Replace(t8,p1,"\r\n");
string r8 = Regex.Replace(t8, p8, "" );
很显然用正则表达式是最方便的
有胆量,值得提倡,你的测试结果我就不公布了,再接再厉
说的 "" 这种情况,我还真的没考虑...
这是我的失误,不光是""这种情况,还有''的情况,然后我加了二行代码,目前是18行ggyz(小虫)
不好意思,说得有点过激,知道这个区高手不少
但我的意思是说,请你们先做了再来评估别人,你连做都没有做,你有什么资格来评论别人?
另外,不是你做不到,别人也做不到,超出意料的事情有很多. fancyf(Fancyray)
刚刚公司上不了网,现在才能上
我把程序放在 www.jinheng.net.cn/release.rar
运行程序点确定,会读取1.txt文件,生成2.txt文件
TO JasonHeung:
有胆量,值得提倡,你的测试结果我就不公布了,再接再厉
...那就是错得非常离谱了??
''不是字符串,而是单个字符另:你用VC写我没法给你做全面的单元测试,但是已经有的Testcase得出了错误的结果我的Testcase还没有包括全部全部的情况
string s = "He say: \"Hello, /*world*/!\".";你的程序生成的2.txt:
string s = "He say: \"Hello, !\"."; 而正确的2.txt应该是:
string s = "He say: \"Hello, /*world*/!\".";
起始字串 结束字串
// \r\n
/* */一次性读出文件。
按字符判断,把“起始字串”和“结束字串”的位置记录到2个Arraylist。循环结束后,根据得到的位置去拼接出个字串。写文件。ok
上班。没时间写代码。只提供思路,参考试试?
按照 转意符的判断,我又增加了三行,现在是 21行代码www.jinheng.net.cn/release.rar请 fancyf(Fancyray) 测试一下控制台程序,只有7K
我是用C#解决的。对你的观点反对。
http://community.csdn.net/Expert/topic/3963/3963478.xml?temp=.652569
sql中查询语句
SELECT * FROM aapower WHERE (CHARINDEX(REPLACE(powerstr, powerstr, powerstr + ','), 'a,b,c,') > 0)转化为oledb中查询语句怎么转化,各位大大指教一下
注:oledb中不能用charindex,replace涵数,如果能用请问怎么用;不要用like %%%%%%来忽悠我,此处是和like相反的查询
access 不支持
//skip the comment
//只要把跳过改成删除就可以了,其他意思差不多了
while( (char)c == '/' ) {
c = sourceReader.read();
if( (char)c == '/' ) {
while( c != 10 )
c = sourceReader.read();
}
else if( (char)c == '*' ) {
c = sourceReader.read();
int b = c;
c = sourceReader.read();
while( (char)b != '*' || (char)c != '/' ) {
b = c;
c = sourceReader.read();
}
}
while( Character.isWhitespace( c = sourceReader.read() ) )
;
}
WHERE (instr(powerstr + ',','a,b,c,') > 0)
To 楼主:
''不是字符串,而是单个字符另:你用VC写我没法给你做全面的单元测试,但是已经有的Testcase得出了错误的结果我的Testcase还没有包括全部全部的情况
让我挺不好意思的,后来才想起来,原来记到SQL里面去了,SQL中 ''可以表字符串
/// <summary>
/// 去除双符号的注解
/// </summary>
/// <param name="MainText"></param>
/// <param name="FlagStart"></param>
/// <param name="FlagEnd"></param>
/// <returns></returns>
string ChangeWithDoubleFlag(string MainText,string FlagStart,string FlagEnd) {
string str=MainText;
string chgValue;
string returnValue;
int Fi1=-1;//First Flag Index;
int Fi2=-1;//Second Flag Index;
Fi1=str.IndexOf(FlagStart);
if(Fi1!=-1)
Fi2=str.IndexOf(FlagEnd,Fi1);
if(Fi1!=-1 && Fi2 ==-1)
Fi2=str.IndexOf("\n",Fi1);
if(Fi1!=-1 && Fi2 !=-1) {
chgValue=str.Remove(Fi1,Fi2-Fi1+FlagEnd.Length);
returnValue=ChangeWithDoubleFlag(chgValue,FlagStart,FlagEnd);
}
else {
returnValue=MainText;
}
return returnValue;
} /// <summary>
/// 去除单符号单行的注解
/// </summary>
/// <param name="MainText"></param>
/// <param name="Flag"></param>
/// <returns></returns>
string ChangeWithSingleFlag(string MainText,string Flag) {
string str=MainText;
string chgValue;
int Fi1=-1;//First Flag Index;
int Fi2=-1;//Second Flag Index;
string returnValue="";
Fi1=str.IndexOf(Flag); if(Fi1!=-1)
Fi2=str.IndexOf("\r\n",Fi1);
if(Fi1!=-1 && Fi2 ==-1)
Fi2=str.IndexOf("\n",Fi1); if(Fi1!=-1 && Fi2 !=-1) {
chgValue=str.Remove(Fi1,Fi2-Fi1) ;
returnValue=ChangeWithSingleFlag(chgValue,Flag);
}
else
returnValue=MainText; return returnValue;
} /// <summary>
/// 移除注解符号
/// </summary>
/// <param name="FileText">代码</param>
/// <returns>移除注解的代码</returns>
public string DropRe(){
if(strRe=="")
strRe="//,/*..*/";
string [] ReFlag=Regex.Split(strRe,",");
for(int i=0;i<=ReFlag.GetUpperBound(0);i++) {
string Rf=ReFlag[i];
if(Rf.IndexOf("..")!=-1) {
string Flag1=Rf.Substring(0,Rf.IndexOf(".."));
string Flag2=Rf.Substring(Rf.IndexOf("..")+2,Rf.Length-Rf.IndexOf("..")-2);
this.code=ChangeWithDoubleFlag(this.code,Flag1,Flag2);
}
else {
this.code=ChangeWithSingleFlag(this.code,Rf);
}
}
return this.code;
}
a = 0;/*-------------------- // 下面是特别公告---------------------*/c = "123//456 /* kdjsdkf */"; /* hehe */d = 'dkdf /* kfjdfj */ kdjskdf' // kdjskjdf /* kfjdskf */
//c = "123//456 /* kdjsdkf */"; /* hehe */d = 'dkdf /* kfjdfj */ kdjskdf' // kdjskjdf /* kfjdskf */c = 1;//"123//456 /* kdjsdkf */"; /* hehe */d = 'dkdf /* kfjdfj */ kdjskdf' // kdjskjdf /* kfjdskf */;string s = "He say: \"Hello, /*world*/!\".";正确的应该是
if(a=b)
a = 0;c = "123//456 /* kdjsdkf */"; d = 'dkdf /* kfjdfj */ kdjskdf'
d = 'dkdf /* kfjdfj */ kdjskdf' c = 1;d = 'dkdf /* kfjdfj */ kdjskdf' string s = "He say: \"Hello, /*world*/!\".";
string newcode = "";
char c = '\0'; for (int i=0;i<code.Length;i++){
c = code[i];
if(c=='"'){
newcode += c.ToString();
i++;
c = code[i];
newcode += c.ToString();
while(i<code.Length-1){
if(c=='"')break;
i++;
c = code[i];
newcode += c.ToString();
}
}else
if(c=='\''){
newcode += c.ToString();
i++;
c = code[i];
newcode += c.ToString();
while(i<code.Length-1){
if(c=='\'')break;
i++;
c = code[i];
newcode += c.ToString();
}
}else
if(c=='/'){ //注解
i++;
c = code[i];
if(c=='*'){ //多行注解
string tmp = "";
tmp += c.ToString();
while(i<code.Length-1){
i++;
c = code[i];
if(c=='/'&&tmp.Length>=4){
if(tmp.Substring(tmp.Length-1,1)=="*")
break;
}
tmp += c.ToString();
}
}else
if(c=='/'){ //单行注解
while(i<code.Length-1){
i++;
c = code[i];
if(c=='\n')break;
}
newcode += "\r\n"; //恢复行注解的回车
}else
newcode += c.ToString();
}else{
newcode += c.ToString();
}
}
textBox2.Text = newcode;
}
src = src.Replace("\\\"","<!!!!>");
src = src.Replace("\\\'","<!!!!!>");
char[] code = src.ToCharArray();
string newcode = "";
char c = '\0'; for (int i=0;i<code.Length;i++){
c = code[i];
if(c=='"'){ newcode += c.ToString();
string tmp = "";
tmp += c.ToString();
i++;
c = code[i];
newcode += c.ToString();
tmp += c.ToString();
while(i<code.Length-1){
if(c=='"')
if(tmp.Substring(tmp.Length-1,1)!="\\")
break;
i++;
c = code[i];
tmp += c.ToString();
newcode += c.ToString();
}
}else
if(c=='\''){
newcode += c.ToString();
i++;
c = code[i];
newcode += c.ToString();
while(i<code.Length-1){
if(c=='\'')break;
i++;
c = code[i];
newcode += c.ToString();
}
}else
if(c=='/'){ //注解
i++;
c = code[i];
if(c=='*'){ //多行注解
string tmp = "";
tmp += c.ToString();
while(i<code.Length-1){
i++;
c = code[i];
if(c=='/'&&tmp.Length>=4){
if(tmp.Substring(tmp.Length-1,1)=="*")
break;
}
tmp += c.ToString();
}
}else
if(c=='/'){ //单行注解
while(i<code.Length-1){
i++;
c = code[i];
if(c=='\n')break;
}
newcode += "\r\n"; //恢复行注解的回车
}else
newcode += c.ToString();
}else{
newcode += c.ToString();
}
}
src = newcode;
src = src.Replace("<!!!!>","\\\"");
src = src.Replace("<!!!!!>","\\\'"); textBox2.Text = src;
}
if(!outcf.Open("2.txt",outcf.modeReadWrite|outcf.modeCreate)){AfxMessageBox("打开文件失败");return 0;} //接收输出 char ch[3] = {'\0'},
single[5] ={'/','/',13,10,'\0'},
multi[5] = {'/','*','*','/','\0'},
symbol[3] = {'\'','\"','\0'},
tmpsymbol[2] = {'\0'},
declare[3] = {'\\','\"','\0'}; BOOL SSTOP = FALSE,MSTOP = FALSE,SYSTOP = FALSE,DSTOP = FALSE; DWORD filelength = (DWORD)cf.GetLength();
int di = 0; for(int i=1;i<=(int)filelength;i++)
{
cf.Read(&ch,2);
if((memcmp(&ch,&declare,2)!=0)&&di<=0){
if((!SSTOP)&&(!MSTOP)&&(memcmp(&ch,&symbol[0],1)==0||memcmp(&ch,&symbol[1],1)==0)&&!SYSTOP){SYSTOP = TRUE;memcpy(&tmpsymbol[0],&ch,1);}
else if((!SSTOP)&&(!MSTOP)&&(memcmp(&ch,&tmpsymbol[0],1)==0)&&SYSTOP)SYSTOP = FALSE;DSTOP = TRUE;} else {if(DSTOP)di=2;DSTOP = FALSE;}
di--;
if((memcmp(&ch,&multi,2)==0)&&!SSTOP&&!SYSTOP)MSTOP = TRUE;
if((memcmp(&ch,&multi[2],2)==0)&&!SSTOP&&!SYSTOP){MSTOP = FALSE;i=i+1;goto Label1; }
if((memcmp(&ch,&single,2)==0)&&!SYSTOP)SSTOP = TRUE;
if((memcmp(&ch,&single[2],2)==0)&&SSTOP&&!SYSTOP)SSTOP = FALSE; if((!SSTOP)&&(!MSTOP))outcf.Write(&ch,1);
Label1:
cf.Seek(i,cf.begin); } cf.Close();
outcf.Close();这样是直接操作文件,如果性能受了影响,可以转到内存操作,性能将大幅提升
当前提供测试的样例不够复杂,望看到你的32个Testcase,多谢!
MyConsoleLab.TestCommentRemover.TestLineComment8 :
String lengths differ. Expected length=20, but was length=35.
Strings differ at index 20.
expected:<"string st=@"aaaa\"; ">
but was:<"string st=@"aaaa\"; //aa 这种情况不在字符串内">
-------------------------------^string content = "string str = @\"/*This is \\\" + \"not a line comment/*/\";";string content = "/*/This is a paragraph comment*/";
string s = @"C:\112312312.txt";
string s = "C:\\123123123.txt";区别在此,在@声明的字符串内不需要增加转义字符……我修改修改代码吧