习题课第一次作业:1、去除C程序中的注释

描述:
C程序的注释用/* */来表示。请写一个程序,将输入的C程序源代码中的注释去掉,输出去掉注释之后的源代码。用于测试的C代码保证符合语法,不使用C++的//注释语法。
注意,C语言不允许出现嵌套注释。具体来说,对于/* /* * /”* /”,如果不允许嵌套注释,那么它表示字符串”* / “;如果允许嵌套注释,它表示一个引号”。字符串中出现的注释符 / * 属于字符串的一部分,注释中出现的双引号”属于注释的一部分。
输入
符合语法的C代码文本文件。代码每行不超过200个字符。
输出
去掉注释后的C代码。要求只能去掉注释,不可以做其他的修改,比如调整缩进,去除注释之外的换行符等。
样例输入

#include 
#include 
#include 

/*Hash Search: 
Hash function: division method; 
handling collisions: open addressing's linear probing. 
In this exercise, M is the basic area's length, all keys are non negative integers.*/

#define M 11

int hash(int key)
{
    return key % M;
}

void init_hash(int* hashtable)
{
    int i;
    for(i = 0; i < M; ++i)
    {
        hashtable[i] = -1;
    }
}

/*return value: 
1:found, *position is the key's index; 
0:not found, *position is where to insert the key; 
-1:overflow. */
int search_hash(int* hashtable, int key, int* position)
{
    int i, h = hash(key);
    for(i = 0; i < M; ++i)
    {
        if(key == hashtable[h])
        {
            *position = h;
            return 1;
        }
        if(-1 == hashtable[h])
        {
            *position = h;
            return 0;
        }
        h = (h+1) % M;
    }
    *position = -1;
    return -1;
}

/*return value: 1:inserted, 0:overflow*/
int insert_hash(int* hashtable, int key)
{
    int position, result;
    result = search_hash(hashtable, key, &position);
    if(-1 == result)
        return 0;
    hashtable[position] = key;
    return 1;
}

void main()
{
    int hashtable[M];
    init_hash(hashtable);
    srand(time(NULL));
    int i, j, key;
    for(i = 0; i < 8; ++i)  /*make a hash table with 8 elements*/
    {
        key = rand() % 50;
        insert_hash(hashtable, key);
        printf("Insert %d\n", key);
        for(j = 0; j < M; ++j)
            printf("%3d", hashtable[j]);
        printf("\n");
    }

    printf("Please input the key to search:\n");
    scanf("%d", &key);
    i = search_hash(hashtable, key, &j);
    if(1 == i)
        printf("Found!Its index is %d\n", j);
    else
        printf("Not found!\n");
}

样例输出

#include 
#include 
#include 



#define M 11

int hash(int key)
{
    return key % M;
}

void init_hash(int* hashtable)
{
    int i;
    for(i = 0; i < M; ++i)
    {
        hashtable[i] = -1;
    }
}


int search_hash(int* hashtable, int key, int* position)
{
    int i, h = hash(key);
    for(i = 0; i < M; ++i)
    {
        if(key == hashtable[h])
        {
            *position = h;
            return 1;
        }
        if(-1 == hashtable[h])
        {
            *position = h;
            return 0;
        }
        h = (h+1) % M;
    }
    *position = -1;
    return -1;
}


int insert_hash(int* hashtable, int key)
{
    int position, result;
    result = search_hash(hashtable, key, &position);
    if(-1 == result)
        return 0;
    hashtable[position] = key;
    return 1;
}

void main()
{
    int hashtable[M];
    init_hash(hashtable);
    srand(time(NULL));
    int i, j, key;
    for(i = 0; i < 8; ++i)  
    {
        key = rand() % 50;
        insert_hash(hashtable, key);
        printf("Insert %d\n", key);
        for(j = 0; j < M; ++j)
            printf("%3d", hashtable[j]);
        printf("\n");
    }

    printf("Please input the key to search:\n");
    scanf("%d", &key);
    i = search_hash(hashtable, key, &j);
    if(1 == i)
        printf("Found!Its index is %d\n", j);
    else
        printf("Not found!\n");
}

提示
注意字符串,字符,转义字符的情况。看看自己有没有考虑”a\”/* ccc */”这种情况。

解决思路:

#pragma warning(disable:4996)//ignore the warning from 15 vs 10
#include <iostream>
#include <string>
using namespace std;
#define LOCAL //redirect the input && output
bool Affected_by_String = false;
bool Affected_by_Annonate = false;
string s,s_get;
void Remove_the_Annotate()
{
    while (getline(cin, s_get))//getLine函数不能读入换行符,需要自己加上
        s += s_get + '\n';
    //待处理的字符串比真实文本多一个字符是有好处的,保证start != end和start + 1都是正确而有效的
    char *start = &s[0];
    char *end = &s[s.length() -1];
    while ( start != end )
    {
        //当前字符有效且既不在字符串中也不在注释中
        while( !Affected_by_String && !Affected_by_Annonate && start != end)
        {
            //当前字符是注释的开始标志,注释标志有效且直到注释符结束之前不予输出,退出当前循环
            if( *(start) == '/' && *(start + 1) == '*' ) 
            {
                Affected_by_Annonate = !Affected_by_Annonate;
                start +=2 ;
            }
            else
            {
                //当前字符串符号未被转义,字符串开始,标注字符串有效标志,退出当前循环
                if(*(start) != '\\' && *(start + 1) == '"' )
                {
                    Affected_by_String = !Affected_by_String ;
                    //注意这里不要写成cout << *start++ << *start++ 
                    //运算符优先级不清楚,包括cout << *start++都需要谨慎使用 
                    cout << *start << *(start + 1 );
                    start += 2;
                }
                else
                    cout << *start++;//当前字符不属于注释或字符串,正常输出
            }       
        }
        while( Affected_by_String && start != end)//字符有效且在字符串内
        {
            //当前字符串结束标志被转义,顺序输出之,当前字符串并未结束
            if( *(start) == '\\' && *(start + 1) == '"' ) 
            {
                cout << *start << *(start + 1 );
                start += 2;
            }
            else
            {
                //字符串退出标志有效,退出当前字符串,并标注下一个字符已不属于字符串
                if( *(start) == '"' )
                {
                    cout << *start++;
                    Affected_by_String = !Affected_by_String ;
                }
                else
                    cout << *start++;
            }
        }
        while( Affected_by_Annonate && start != end )
        {
            //注释结束标志有效,与注释开始标志同样的处理
            if( *(start) == '*' && *(start + 1) == '/' ) 
            {
                start +=2 ;
                Affected_by_Annonate = !Affected_by_Annonate;
            }               
            else
                start++;//否则在注释内的内容还是被忽略掉
        }
    }
}
int main()
{
#ifdef LOCAL
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
#endif
    Remove_the_Annotate();
    return 0;
}

后续:程序中还有bug。bug-1:在end的位置是否有效、start + 1的位置是否有效等均可以在字符创末尾额外添加一个换行符来处理。当然还有可能没有发现的bug,如只出现左半边注释符,miss右半边注释符的时候,可能会出现异常。提交平台通过,bug_1没有被发现估计与string动态增长的方式有关,仍需注意。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值