程序员面试宝典上面的题目有很多是很经典的问题,可供我们思考,而且会对我们面试有很大好处。
下面是第45页的一个题目:编写一个函数,实现把C/C++程序代码中的注释去掉,我开始看的时候总是看不懂,后来在网上看到一个网友详细的分析了其代码,但是我看了之后觉得有好多地方他分析的都不对,于是,我自己又花了半天的时间分析了一遍,觉得自己理解了,下面给出我的分析语句。如果还有不严谨的部分,请指教!
/********************************************************
功能:去除C/C++中的注释
输入:指向C/C++程序代码的指针及长度
来源:程序员面试宝典第45页
分析:一次读取一行,分两种情况,因为有两种注释:
(1)在读取到的一行中查找“//”,如果找到,则把“//”及其后的部分扔掉。
(2)在读取到的一行中查找“/*”,记录位置pos1,然后再在这行中查找“*/”,如果找到,也记录位置pos2,扔掉它们与其中的内容,以pos2开始,继续查找“/*”;如果在当前行中没有找到,则去掉当前行中“/*”及其后的内容,读取新的一行,查找“*/”,如没有。则去掉读取到的这一行,再读一行,查找“*/”,如找到,记录位置pos2,去掉这一行的0到pos2之间的字符。
(3)进行步骤1、步骤2,直到程序结束。
编程时要考虑的特殊情况i:
这道题实现我表示很蛋疼,太肯跌了
#include "stdio.h"
#include "stdlib.h"
#define MAXBUF 102400
void removeComment(char *buf,int length)
{
char *p,*end,c;
int len;
char *singleQuota,*doubleQuota,*lc_start,*bc_start;
singleQuota = NULL;
doubleQuota = NULL;
lc_start = NULL;
bc_start = NULL;
p =buf;
end = buf+length;
while(p<end)
{
c = *p;
switch(c)
{
case '\'':
if(doubleQuota || lc_start||bc_start)
{
p++;
continue;
}
else if(singleQuota == NULL)
{
singleQuota = p++;
continue;
}
else
{
c=*(p-1);
len = p-singleQuota;
if(len == 2 &&c=='\\')
{
p++;
continue;
}
singleQuota = NULL;
}
break;
case '\"':
if(singleQuota ||lc_start||bc_start)
{
p++;
continue;
}
else if(doubleQuota == NULL)
{
doubleQuota = p++;
continue;
}
else
{
c = *(p-1);
if(c=="\\")
{
p++;
continue;
}
}
p++;
doubleQuota = NULL;
break;
case '/':
if(singleQuota ||lc_start||bc_start||doubleQuota)
{
p++;
continue;
}
c = *(p+1);
if(c=='/')
{
lc_start = p;
p+=2;
}
else if(c=='*')
{
bc_start = p;
p+=2;
}
else
{
p++;
}
break;
case '*':
if(singleQuota ||doubleQuota ||lc_start||bc_start==NULL)
{
p++;
continue;
}
c = *(p+1);
if(c == '/')
{
p+=2;
/*这里出了一个bug应该是bc清空*/
memset(bc_start,' ',p-bc_start);
lc_start =NULL;
}
else
{
p++;
}
break;
case '\n':
if(lc_start == NULL)
{
p++;
continue;
}
if(lc_start)
{
c = *(p-1);
memset(lc_start,' ',(c=='\r')?(p++-1-lc_start):(p++-lc_start));
lc_start=NULL;
}
break;
default:
p++;
break;
}
}
if(lc_start)/*这里很重要,如果在文件末尾的地方有 这种//双斜杠的注释的话 还是需要考虑的*/
{
memset(lc_start,' ',p-lc_start);
}
}
int main()
{
char buf[MAXBUF];
char c;
int i=0;
int fd;
fd = fopen("test.c","r");
if(fd == NULL)
{
exit(0);
}
while((c=fgetc(fd))!=EOF)
{
buf[i++]=c;
}
fclose(fd);
removeComment(buf,i);
buf[i]='\0';
printf("%s",buf);
return 0;
}
要是遇到还好,感觉看起来容易,实现起来就有点复杂了,苦逼啊