从C风格字符串中删除C风格注释的函数问题

4
我正在尝试创建一个函数,用于从字符串中移除C风格的注释。在使用指针遍历字符数组时,我尝试使用经典的while循环,现在通过使用两个指针(p2p1多一步,它们都从开头开始)。我尝试检查*p1 == '/' and when *p2 == '*',当它为真时,我会创建两个新指针,这些指针会找到注释的结尾(*p3 == '*' & & *p4 == '/'),然后我会创建两个新指针p5p6 ,其中第一个指针将指向注释中的第一个字符'/ ',第二个指针将指向应删除的最后一个字符p4。我尝试使用while循环执行 while(*p5++ = *p6++); ,但遗憾的是这没有起作用。
#include <stdio.h>

void remove_comments(char* s) {

    char *p1=s;
    char *p2 = s;   
        p2++; // move p2 ahead of p1;


    while(*p1 !='\0' && *p2 !='\0') { 

        if(*p1=='/' && *p2=='*') { // beginning of comment
            char *p3 = p1; // save their positions and
            char *p4 = p2; //create two new pointers

            while(*p3 !='\0' && *p4 !='\0') {
            if(*p3 == '*' && *p4 == '/') { //if end of comment

                    char *p5 = p1;
                    char *p6 = p4;

                    while(*p5++ = *p6++);

                } else p1++;

                p3++;
                p4++;

            }




        }
        p1++;
        p2++;


    }




    }




int main() {


    char arr[] = "This is an /*this is a comment*/ example!";

    remove_comments(arr);

    printf("%s", arr);



    return 0;
}

上述代码应该输出This is an example!,但字符串没有改变。我该如何修复?

2
现在是你学习使用调试器的理想时机。 - Weather Vane
2
这是K&R的一个常见练习,还有许多其他例子,包括直接从getchar()流出的例子。这个问题本质上是由一个打字错误引起的,因此并不是非常有趣。 - Antti Haapala -- Слава Україні
@AnttiHaapala 这也是由于s1的不必要增量引起的。 - S.S. Anne
1
解决这种问题的好策略是绘制一个状态机。 - Caleb
@AnttiHaapala 这个问题是由于一个打字错误,不必要的对 s1 的增量以及我没有意识到在初始化 p6 时需要将 p4 向后移动一个位置。我建议您等待问题解决,这样您就可以查看我产生的所有错误,以免因为您认为这是由于打字错误和不必要的对 s1 的增量而将问题标记为离题。谢谢。 - l0ner9
显示剩余3条评论
1个回答

1

请打开编译器警告 (gcc -Wall)。

这是之前版本的代码:

test.c: In functionremove_comments’:
test.c:11:29: warning: comparison between pointer and integer
         if(*p1 == '/' && p2 == '*')
                             ^~

使问题的一部分变得非常明显(它无法检测序列)。
更改为:
        if(*p1=='/' && p2=='*') { // beginning of comment

转换为:

        if(*p1=='/' && *p2=='*') { // beginning of comment

当你不需要时,你正在增加 s1,这会导致错误。

移除此内容:

                else
                    p1++;

除此之外,这里的代码:

                if(*p3 == '*' && *p4 == '/')
                { // if end of comment

                    char *p5 = p1;
                    char *p6 = p4;

p4复制斜杠。将该块更改为以下内容:
                if(*p3 == '*' && *p4 == '/')
                { // if end of comment

                    char *p5 = p1;
                    char *p6 = p4+1;

并且,结合其他更改,您的代码可以工作。

我建议将while(*p5++ = *p6++);更改为strcpy(p5, p6);; strcpy可能会更快。

它不会产生您精确期望的输出,但它会删除/**/之间的所有字符,包括它们本身。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接