一道簡單的筆試題


要求:將C++源代碼中的註釋去掉


即,對於下列源代碼


#include <iostream> // comment1

using namespace std;

/* comment 2

// #include <string> 
*/
 int main( int argc,char *argv[] /*comment 3*/ )
{
    
return 1;
}


處理後應輸出

#include <iostream>

using namespace std;

int main(int argc, char * argv[])
{
    
return 1;
}


函數原型: void foo( const char * src,char * buf, unsigned char * buf_len);
其中src爲源代碼緩衝區,buf爲輸出緩衝區,buf_len爲輸出緩衝區的長度,又已知源代碼長度不會超過1M。

編程思路很簡單,基於一個簡單的三狀態的有窮自動機即可。foo()函數在執行過程中將在三種狀態中進行轉換:代碼、舊式註釋(//)和新式註釋(/* */ )。三種狀態之間的轉換件如下

    當處於代碼狀態時,如果後續兩個字符爲'//',則進入舊式註釋;若後續兩個字符爲'/*',則進入新式註釋;否則保持當前狀態,並將下一個字符複製進輸出緩衝區。三種情況下都要對讀指針進行相應的調整。

    當處於舊式註釋狀態時,如果下一個字符爲'/n'(換行符),則進入代碼狀態,並且將'/n'也複製進輸出緩衝區;否則仍保持當前狀態。兩種情況下都要對讀指針進行相應的調整。

    當處於新式註釋狀態時,如果下兩個字符爲'*/',則進入代碼狀態;否則保持當前狀態。兩種情況下都要對讀指針進行相應的調整。
 

實現代碼如下:
#include <iostream>
#include 
<fstream>
using namespace std;

const char STAR='*';
const char SLASH='/';
const char NEWLINE=' ';
const unsigned int MAX=1048576;


enum State
{
    CODE,
    OLD_STYLE,
    NEW_STYLE,
}
;

void foo(const char * src,char * buf, unsigned int buf_len)
{
    State state
=CODE;

    
const char * ptr= src;
    unsigned 
int count=0;

    
while(     count<(buf_len-1)
        
&& count<MAX
     )
    
{
    
switch(state)

    
{
        
case CODE:
        
        
if*ptr==SLASH && *(ptr+1)==SLASH)
        
{
            state
=OLD_STYLE;
            ptr
+=2;
        }

        
else if*ptr==SLASH && *(ptr+1)==STAR)
        
{
            state
=NEW_STYLE;
            ptr
+2;
        }

        
else
        
{
            buf[count
++]=*ptr;
            ptr
++;
        }


        
break//end of case CODE

        
case OLD_STYLE:
        
        
if*ptr==NEWLINE)
        
{
            state
=CODE;
            buf[count
++]=*ptr;        //注意這裏不要在輸出中遺漏換行符
            ptr++;
        }

        
else
        
{
            ptr
++;
        }


        
break;//end of case OLD_STYLE

        
case NEW_STYLE:

        
if*ptr==STAR && *(ptr+1)==SLASH)
        
{
            state
=CODE;
            
//如果註釋結束緊接着換行符的話,要跳過這個換行符
            if*(ptr+2)==NEWLINE )   
            ptr
+=3;
            
else
            ptr
+=2;
        }

        
else
        
{
            ptr
++;
        }


        
break;// end of case NEW_STYLE
       
        
default:
        cout
<<"Oh,should not happen!"<<endl;


    }
 //end of switch


    }
// end of while

    buf[count
++]='';
    
    
return ;
}

int main(int argc,char *argv[])
{

    
char source[MAX]=    {'',};
    
char stripped[MAX]=    {'',};
    
    
    ifstream original_file(
"input");
    original_file.read(source,MAX);

    foo ( source,stripped,
sizeof(source));

    ofstream stripped_file(
"output");
    stripped_file.write(stripped,strlen(stripped));

    original_file.close();
    stripped_file.close();


    
return 1;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章