K& R Exe。 1-23:一些并发症

时间:2016-10-10 01:01:52

标签: c comments

"练习1-23。编写程序以删除C程序中的所有注释。 不要忘记处理引用的字符串和字符常量 正常。 C评论不嵌套。" K& R pg.34

基本上,我有两个问题:

1)我是一个全新的编码,我想知道我是否至少以正确的方式思考问题。

2)代码构建为忽略//\n/**/。但是,/*评论总是留下一个/

输入: abc/*comment*/123

输出: abc/123

输入: abc/*123

输出: abc/

#include <stdio.h>
char s[1000]; //Principal array
int countS; //Number of char in array

int deletSingleLineComments(void);
int deletMultiLineComments(void);

int main(void){
    int c;
    while((c=getchar())!=EOF){
        s[countS]=c;
        ++countS;
    }

    deletMultiLineComments(); //Function 1
    deletSingleLineComments(); //Function 2

    printf("\ns[]=\n%s\n\ncountS[]=%d\n",s,countS);
}



//Functions 1
int deletMultiLineComments(void){
    char t[1000];
    int i=0;
    int inComment=0;
    int diff=0;
    int a,b,c;

    while(i<=countS){ 
        t[i]=s[i];
        ++i;
    }
    i=0;

    while(i<=countS){

        if(t[i]=='/' && t[i+1]=='*'){ 
            inComment=1;
        }

        if(inComment==1){
            ++diff; //to equilibrate the number
        }

        if(inComment==0){
            s[i-diff]=t[i];
        }

        if(t[i]=='*' && t[i+1]=='/'){
            inComment=0;
        }
        ++i;
    }
    s[i-diff+1]='\0';
    countS=i-diff;

    printf("\nt[]=\n%s\n",t);
}



//Function 2
int deletSingleLineComments(void){
    int i=0;
    char t[1000];
    int inComment=0;
    int diff=0;

    while(i<=countS){
        t[i]=s[i];
        ++i;
    }
    i=0;

    while(i<=countS){

        if(t[i] == '/' && t[i+1] == '/'){
            inComment=1;
        }

        if(t[i]=='\n'){
            inComment=0;
        }

        if(inComment==1){
            ++diff;
        }

        if(inComment==0){
            s[i-diff]=t[i];
        }
        s[i-diff+1]='\0';
        ++i;
    }
    countS=i-diff;
}

谢谢。

1 个答案:

答案 0 :(得分:0)

while(i<=countS){ t[i]=s[i];... }

请注意,字符串基于零。例如,"ABC"的长度为3,它从零索引开始,最后一个有效索引为2(不是3)。因此,您应该将条件更改为i < string_length

while(i < countS){ t[i]=s[i];... }

访问t[i+1]时也要小心,因为i有效时,i+1可能会超出范围。

if (i < (countS - 1))
    if(t[i]=='/' && t[i+1]=='*')

为了将一个字符串分配给另一个字符串,您可以引入第二个变量k,并在每次分配后增加k。这个方法(在我看来)比使用diff变量并进行加法和减法更容易。

此外,您可以使用char t[1000];来声明一个长度为char *t = malloc(countS);的临时变量,而不是countS,然后必须在free(t)结束时释放它。如果您的编译器支持可变长度数组,则可以放置char t[countS]

示例:

char s[1000]; //Principal array
int countS; //Number of char in array

//Functions 1
void deletMultiLineComments(void) 
{
    char *t = malloc(countS);
    int i = 0;
    int k = 0;
    int inComment = 0;

    while (i < countS)
    {
        t[i] = s[i];
        ++i;
    }

    i = 0;
    while (i < countS) 
    {
        if (i < countS - 1)
        if (t[i] == '/' && t[i + 1] == '*') 
        {
            inComment = 1;
            i+=2;
            continue;
        }

        if (inComment == 1) 
        {
            if (i < countS - 1)
            if (t[i] == '*' && t[i + 1] == '/')
            {
                inComment = 0;
                i+=2;
                continue;
            }
        }

        if (inComment == 0) 
        {
            s[k] = t[i];
            k++;
        }

        ++i;
    }

    free(t);
    s[k] = '\0';
    countS = k;

    printf("mulitline comment removed %s\n", s);
}

//Function 2
void deletSingleLineComments(void) 
{
    char *t = malloc(countS);
    int i = 0;
    int k = 0;
    int inComment = 0;

    while (i < countS) 
    {
        t[i] = s[i];
        ++i;
    }

    i = 0;
    while (i < countS) 
    {
        if (i < countS - 1)
            if (t[i] == '/' && t[i + 1] == '/')
            {
                inComment = 1;
                i += 2;
                continue;
            }

        if (t[i] == '\n')
        {
            inComment = 0;
        }

        if (inComment == 0) 
        {
            s[k] = t[i];
            k++;
        }

        i++;
    }
    free(t);    
    s[k] = '\0';
    countS = k;

    printf("single comment removed %s\n", s);
}

int main(void) 
{
    //get input
    scanf("%s", s);

    countS = 0;
    while (s[countS]) countS++;

    deletMultiLineComments(); //Function 1
    deletSingleLineComments(); //Function 2
}