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

K&R Exe. 1-23 : Some Complications

"练习 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]='[=10=]';
    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]='[=10=]';
        ++i;
    }
    countS=i-diff;
}

谢谢。

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 = malloc(countS);声明一个长度为countS的临时变量,而不是char t[1000];,然后必须在最后用[=28]释放它=].如果你的编译器支持可变长度数组,你可以只输入 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] = '[=13=]';
    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] = '[=13=]';
    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
}