編寫一個函數,實現把C/C++程序代碼中的註釋去掉,並把結果返回。

原文鏈接:https://blog.csdn.net/wojiaopanpan/article/details/7405859

程序員面試寶典上面的題目有很多是很經典的問題,可供我們思考,而且會對我們面試有很大好處。

下面是第45頁的一個題目:編寫一個函數,實現把C/C++程序代碼中的註釋去掉,我開始看的時候總是看不懂,後來在網上看到一個網友詳細的分析了其代碼,但是我看了之後覺得有好多地方他分析的都不對,於是,我自己又花了半天的時間分析了一遍,覺得自己理解了,下面給出我的分析語句。如果還有不嚴謹的部分,請指教!

/********************************************************
 功能:去除C/C++中的註釋
 輸入:指向C/C++程序代碼的指針及長度
 來源:程序員面試寶典第45頁

分析:一次讀取一行,分兩種情況,因爲有兩種註釋:

(1)在讀取到的一行中查找“//”,如果找到,則把“//”及其後的部分扔掉。

(2)在讀取到的一行中查找“/*”,記錄位置pos1,然後再在這行中查找“*/”,如果找到,也記錄位置pos2,扔掉它們與其中的內容,以pos2開始,繼續查找“/*”;如果在當前行中沒有找到,則去掉當前行中“/*”及其後的內容,讀取新的一行,查找“*/”,如沒有。則去掉讀取到的這一行,再讀一行,查找“*/”,如找到,記錄位置pos2,去掉這一行的0到pos2之間的字符。

(3)進行步驟1、步驟2,直到程序結束。

編程時要考慮的特殊情況i:

“”中的“//”“/*”

''中的“//”“/*”

“//”與“/*”的嵌套關係,比如///* 、/*  //*/
 *********************************************************/

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>


/**
 * 功能:移除C/C++程序代碼中的註釋
 *
 * 輸入:指向C/C++程序代碼的指針
 */

void remove_comment(char *buf, size_t size)
{
    char *p, *end, c;
    char *sq_start, *dq_start;
    char *lc_start, *bc_start;
    size_t len;

    p = buf;
    end = p + size;

    sq_start = NULL;
    dq_start = NULL;

    lc_start = NULL;
    bc_start = NULL;

    while (p < end)
    {

        c = *p;

        switch (c)
        {

        case '\'': /* 單引號 */
            if (dq_start || lc_start || bc_start)
            {
                /* 忽略字符串與註釋中的單引號 */
                p++;
                continue;
            }

            if (sq_start == NULL)
            {
                sq_start = p++;

            }
            else
            {
                len = p++ - sq_start;

                if (len == 2 && *(sq_start + 1) == '\\')
                {
                    /* 忽略字符中的單引號 */
                    continue;
                }

                sq_start = NULL;
            }

            break;

        case '\"': /* 雙引號 */
            if (sq_start || lc_start || bc_start)
            {
                /* 忽略字符或註釋中的雙引號 */
                p++;
                continue;
            }

            if (dq_start == NULL)
            {
                dq_start = p++;

            }
            else
            {
                if (*(p++ - 1) == '\\')
                {
                    /* 忽略字符串中的雙引號 */
                    continue;
                }

                dq_start = NULL;
            }

            break;

        case '/': /* 斜杆 */
            if (sq_start || dq_start || lc_start || bc_start)
            {
                /* 忽略字符、字符串或註釋中的斜杆 */
                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 (sq_start || dq_start || lc_start || bc_start == NULL)
            {
                /* 忽略字符、字符串或行註釋中的星號,還有忽略乘號 */
                p++;
                continue;
            }

            if (*(p + 1) != '/')
            {
                /* 忽略塊註釋中的星號 */
                p++;
                continue;
            }

            p += 2;

            memset(bc_start, ' ', p - bc_start);

            bc_start = NULL;

            break;

        case '\n': /* 換行符 */
            if (lc_start == NULL)
            {
                p++;
                continue;
            }

            c = *(p - 1);

            memset(lc_start, ' ',
                   (c == '\r' ? (p++ - 1) : p++) - lc_start);

            lc_start = NULL;

            break;

        default:
            p++;
            break;
        }
    }

    if (lc_start)
    {
        memset(lc_start, ' ', p - lc_start);
    }
}


int
main(int argc, char *argv[])
{
    int fd, n;
    char buf[102400];

    fd = open("D:\hdu1533.cpp",
              _O_RDONLY, 0);
    if (fd == -1)
    {
        return -1;
    }

    n = read(fd, buf, sizeof(buf));
    if (n == -1 || n == 0)
    {
        close(fd);
        return -1;
    }

    //printf("test\n");

    remove_comment(buf, n);

    *(buf + n) = '\0';

    printf(buf);
    /***********\\\/////// */

    close(fd);

    return 0;
}

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