IT이야기

C/C++ 코드에서 주석 제거

cyworld 2022. 4. 22. 21:05
반응형

C/C++ 코드에서 주석 제거

사전 처리를 하지 않고 C/C++ 소스 파일에서 코멘트를 쉽게 제거할 수 있는 방법이 있는가?(즉, gcc -E를 사용할 수 있을 것 같은데, 이렇게 하면 매크로가 확장될 것이다.)나는 단지 코멘트가 벗겨진 소스 코드를 원한다. 다른 것은 변경해서는 안 된다.

편집:

기존 도구에 대한 선호도.나는 이것을 직접 regexes로 쓰고 싶지 않다. 나는 코드에서 너무 많은 놀라움을 예상한다.

원본 파일에서 다음 명령을 실행하십시오.

gcc -fpreprocessed -dD -E test.c

케니 덕분에올바른 플래그를 찾기 위한 TM.완전성을 위한 결과는 다음과 같다.

test.c:

#define foo bar
foo foo foo
#ifdef foo
#undef foo
#define foo baz
#endif
foo foo
/* comments? comments. */
// c++ style comments

gcc -fpreprocessed -dD -E test.c:

#define foo bar
foo foo foo
#ifdef foo
#undef foo
#define foo baz
#endif
foo foo

그것은 너의 의견이 얼마나 비뚤어져 있느냐에 달려 있다.나는 프로그램이 있다.sccC와 C++의 코멘를는는은 는. 있고,의 4)를 나 또한 그것을 위한 테스트 파일을 가지고 있고, 나는 현재 선택된 답안에 있는 옵션들로 GCC (MacOS X의 4.2.1)를 시도해 보았는데, GCC는 테스트 케이스에서 끔찍하게 악화된 몇몇 코멘트를 완벽하게 처리하지 못하는 것 같다.

NB: 이것은 실제적인 문제가 아니다 - 사람들은 그런 무시무시한 코드를 쓰지 않는다.

테스트 사례의 (하위 세트 - 총 135개 라인 중 36개 라인)를 고려하십시오.

/\
*\
Regular
comment
*\
/
The regular C comment number 1 has finished.

/\
\/ This is not a C++/C99 comment!

This is followed by C++/C99 comment number 3.
/\
\
\
/ But this is a C++/C99 comment!
The C++/C99 comment number 3 has finished.

/\
\* This is not a C or C++ comment!

This is followed by regular C comment number 2.
/\
*/ This is a regular C comment *\
but this is just a routine continuation *\
and that was not the end either - but this is *\
\
/
The regular C comment number 2 has finished.

This is followed by regular C comment number 3.
/\
\
\
\
* C comment */

gcc -fpreprocessed -dD -E subset.c)은 다음과 같다.

/\
*\
Regular
comment
*\
/
The regular C comment number 1 has finished.

/\
\/ This is not a C++/C99 comment!

This is followed by C++/C99 comment number 3.
/\
\
\
/ But this is a C++/C99 comment!
The C++/C99 comment number 3 has finished.

/\
\* This is not a C or C++ comment!

This is followed by regular C comment number 2.
/\
*/ This is a regular C comment *\
but this is just a routine continuation *\
and that was not the end either - but this is *\
\
/
The regular C comment number 2 has finished.

This is followed by regular C comment number 3.
/\
\
\
\
* C comment */

'scc'의 출력은 다음과 같다.

The regular C comment number 1 has finished.

/\
\/ This is not a C++/C99 comment!

This is followed by C++/C99 comment number 3.
/\
\
\
/ But this is a C++/C99 comment!
The C++/C99 comment number 3 has finished.

/\
\* This is not a C or C++ comment!

This is followed by regular C comment number 2.

The regular C comment number 2 has finished.

This is followed by regular C comment number 3.

'scc -C'(이중 슬래시 코멘트를 인식)의 출력은 다음과 같다.

The regular C comment number 1 has finished.

/\
\/ This is not a C++/C99 comment!

This is followed by C++/C99 comment number 3.

The C++/C99 comment number 3 has finished.

/\
\* This is not a C or C++ comment!

This is followed by regular C comment number 2.

The regular C comment number 2 has finished.

This is followed by regular C comment number 3.

GitHub에서 SCC 소스 이용 가능

Git 버전이 2017-01-18년(미국/태평양 표준시)에 만들어졌지만 현재 SCC 버전은 6.60(2016-06-12일자)이다.이 코드는 GitHub https://github.com/jleffler/scc-snapshots에서 이용할 수 있다.이전 릴리스의 스냅샷(4.03, 4.04, 5.05)과 두 개의 사전 릴리스(6.16, 6.50)도 찾을 수 있으며, 모두 태그가 지정되어 있음release/x.yz.

그 코드는 여전히 RCS에 의해 주로 개발된다.하위 모듈이나 이와 유사한 메커니즘을 사용하여 다음과 같은 일반적인 라이브러리 파일을 처리하는 방법을 아직 구상 중 입니다.stderr.c그리고stderr.h(https://github.com/jleffler/soq)에서도 확인할 수 있다.

SCC 버전 6.60은 이진수, 숫자 문장 부호, 원시 문자열, 16진수 부동액과 같은 C+++11, C++14 및 C++17 구성체를 이해하려고 시도한다.기본값은 C11 모드 작동이다.(참고)의 의미는-C플래그 - 위에서 언급된 — 답안의 본문에 기술된 버전 4.0x와 현재 최신 버전인 버전 6.60 사이에서 뒤집혔다.)

C를 사용하기 때문에 C에게 "자연적인" 것을 사용하는 것이 좋을 것이다.당신은 C 전처리기기를 사용하여 코멘트를 제거할 수 있다.아래에 제시된 예는 GCC의 C 전처리에 관한 것이다.또한 다른 C 퍼프로세서와 동일하거나 유사한 방법으로 작업해야 한다.

C의 경우 사용

cpp -dD -fpreprocessed -o output.c input.c

또한 다음과 같은 JSON의 코멘트를 제거하는 데도 효과가 있다.

cpp -P -o - - <input.json >output.json

C 전처리기구에 직접 접근할 수 없는 경우 교체해 보십시오.cpp와 함께cc -EC 컴파일러가 전처리기 단계 후에 멈추라고 하는군C 컴파일러 바이너리가 아닌 경우cc바꿀 수 있다cc예를 들어, C 컴파일러 이진 이름clang. 모든 사전 프로세서가 지원하는 것은 아니라는 점에 유의하십시오.-fpreprocessed.

gcc -fprepreprocessed -D -E는 나에게 효과가 없었지만 이 프로그램은 다음과 같이 한다.

#include <stdio.h>

static void process(FILE *f)
{
 int c;
 while ( (c=getc(f)) != EOF )
 {
  if (c=='\'' || c=='"')            /* literal */
  {
   int q=c;
   do
   {
    putchar(c);
    if (c=='\\') putchar(getc(f));
    c=getc(f);
   } while (c!=q);
   putchar(c);
  }
  else if (c=='/')              /* opening comment ? */
  {
   c=getc(f);
   if (c!='*')                  /* no, recover */
   {
    putchar('/');
    ungetc(c,f);
   }
   else
   {
    int p;
    putchar(' ');               /* replace comment with space */
    do
    {
     p=c;
     c=getc(f);
    } while (c!='/' || p!='*');
   }
  }
  else
  {
   putchar(c);
  }
 }
}

int main(int argc, char *argv[])
{
 process(stdin);
 return 0;
}

이렇게 할 수 있는 것 이상의 스트립cmt 프로그램이 있다.

StripCmt는 C, C++, Java 소스 파일에서 코멘트를 제거하기 위해 C로 작성된 간단한 유틸리티다.유닉스 텍스트 처리 프로그램의 대 전통에서는 FIFO(First In - First Out) 필터로 기능하거나 명령줄에서 인수를 받아들일 수 있다.

(hlovdal의 대답에 따라: 이것에 대한 Python 코드에 대한 질문)

나도 이런 문제가 있었어.나는 나에게 효과가 있는 이 도구를 찾았다.그러나 코멘트 라인이 다음 라인으로 확장되는지는 무시한다.예:

// this is my comment \
comment continues ...

이럴 때는 프로그램에서 길을 찾을 수가 없어서 그냥 무시된 줄만 검색하고 수작업으로 고쳤다.나는 그것을 위한 선택권이 있을 것이라고 믿는다. 그렇지 않으면 당신은 프로그램의 원본 파일을 바꿀 수 있을 것이다.

표준 C 라이브러리를 사용하여 C 프로그램을 작성하는데, 약 200줄 정도가 C 소스 코드 파일의 코멘트를 삭제한다.qetzy/remitcomments

행동

  1. 멀티 라인에 걸쳐 있거나 전체 라인을 차지하는 C 스타일 코멘트가 영점 처리된다.
  2. 줄 가운데에 있는 C 스타일 코멘트는 변함이 없다.예를 들어,void init(/* do initialization */) {...}
  3. 전체 라인을 차지하는 C++ 스타일 코멘트가 영점 처리된다.
  4. 확인을 통해 C 문자열 리터럴이 존중됨"그리고\".
  5. 직선을 긋다이전 행이 다음으로 끝나는 경우\ current line 은 laugh atthe dayda.
  6. 줄 번호는 그대로 유지된다.영점 처리된 선 또는 선의 일부가 비어 있음

테스트 & 프로파일링

는 코멘트가 많은 가장cpython 소스 코드로 테스트했다.이 경우 작업을 정확하고 빠르게 수행하며, gcc보다 2-5배 빠름

time gcc -fpreprocessed -dD -E Modules/unicodeobject.c > res.c 2>/dev/null
time ./removeccomments < Modules/unicodeobject.c > result.c

사용법

/path/to/removeccomments < input_file > output_file

최근에 나는 이 문제를 해결하기 위해 루비 코드를 썼다.다음과 같은 예외를 고려했다.

  • 줄담배를 드리다
  • 한 줄에 여러 줄 코멘트, 욕심 많은 일치를 고친다.
  • 여러 줄의 여러 줄

암호는 다음과 같다.

코멘트가 문자열로 나타날 경우를 대비하여 각 행을 사전 처리할 때 다음 코드를 사용한다.그게 네 코드에 나타나면, 어, 운이 나빴어.좀 더 복잡한 현으로 대체할 수 있다.

  • MUL_REFACE_LEFT = "MUL_REFACE_LEFT"
  • MUL_REFACE_RITE = "MUL_REFACE_RITE"
  • SIG_REFACE = "SIG_REFACE"

사용법:ruby -w inputfile outputfile

이것은 //one-line 및 /* multi-line */ comments를 제거하기 위한 perl 스크립트 입니다.

  #!/usr/bin/perl

  undef $/;
  $text = <>;

  $text =~ s/\/\/[^\n\r]*(\n\r)?//g;
  $text =~ s/\/\*+([^*]|\*(?!\/))*\*+\///g;

  print $text;

명령줄 인수로 원본 파일을 필요로 한다.스크립트를 파일에 저장한 후 remove_comments.pl이라고 하고 perl -w remove_comments 명령을 사용하여 호출하십시오.[소스 파일]

도움이 되길 바래.

#include<stdio.h>
{        
        char c;
        char tmp = '\0';
        int inside_comment = 0;  // A flag to check whether we are inside comment
        while((c = getchar()) != EOF) {
                if(tmp) {
                        if(c == '/') {
                                while((c = getchar()) !='\n');
                                tmp = '\0';
                                putchar('\n');
                                continue;
                        }else if(c == '*') {
                                inside_comment = 1;
                                while(inside_comment) {
                                        while((c = getchar()) != '*');
                                        c = getchar();
                                        if(c == '/'){
                                                tmp = '\0';
                                                inside_comment = 0;
                                        }
                                }
                                continue;
                        }else {
                                putchar(c);
                                tmp = '\0';
                                continue;
                        }
                }
                if(c == '/') {
                        tmp = c;
                } else {
                        putchar(c);
                }
        }
        return 0;
}

이 프로그램은 // 및 /.../와 같은 조건 모두에서 실행된다.

I believe 만약 당신이 하나의 문장을 사용한다면 당신은 C에서 코멘트를 쉽게 제거할 수 있을 것이다.

perl -i -pe ‘s/\\\*(.*)/g’ file.c This command Use for removing * C style comments 
perl -i -pe 's/\\\\(.*)/g' file.cpp This command Use for removing \ C++ Style Comments

이 명령의 문제만 둘 이상의 행을 포함하는 주석을 제거할 수 없다.그러나 이 regEx를 사용하면 다중라인 삭제 코멘트를 위한 논리를 쉽게 구현할 수 있다.

늦은 건 알지만, 코드와 컴파일러 작성 첫 시도를 나눠야겠다고 생각했다.

참고: 이 내용은 다음을 설명하지 않는다."\*/"여러 줄의 코멘트 안에서./\*...."*/"...\*한편, gcc 4.8.1 역시 그렇지 않다.

void function_removeComments(char *pchar_sourceFile, long long_sourceFileSize)
{
    long long_sourceFileIndex = 0;
    long long_logIndex = 0;

    int int_EOF = 0;

    for (long_sourceFileIndex=0; long_sourceFileIndex < long_sourceFileSize;long_sourceFileIndex++)
    {
        if (pchar_sourceFile[long_sourceFileIndex] == '/' && int_EOF == 0)
        {
            long_logIndex = long_sourceFileIndex;  // log "possible" start of comment

            if (long_sourceFileIndex+1 < long_sourceFileSize)  // array bounds check given we want to peek at the next character
            {
                if (pchar_sourceFile[long_sourceFileIndex+1] == '*') // multiline comment
                {
                    for (long_sourceFileIndex+=2;long_sourceFileIndex < long_sourceFileSize; long_sourceFileIndex++)
                    {
                        if (pchar_sourceFile[long_sourceFileIndex] == '*' && pchar_sourceFile[long_sourceFileIndex+1] == '/')
                        {
                            // since we've found the end of multiline comment
                            // we want to increment the pointer position two characters
                            // accounting for "*" and "/"
                            long_sourceFileIndex+=2;  

                            break;  // terminating sequence found
                        }
                    }

                    // didn't find terminating sequence so it must be eof.
                    // set file pointer position to initial comment start position
                    // so we can display file contents.
                    if (long_sourceFileIndex >= long_sourceFileSize)
                    {
                        long_sourceFileIndex = long_logIndex;

                        int_EOF = 1;
                    }
                }
                else if (pchar_sourceFile[long_sourceFileIndex+1] == '/')  // single line comment
                {
                    // since we know its a single line comment, increment file pointer
                    // until we encounter a new line or its the eof 
                    for (long_sourceFileIndex++; pchar_sourceFile[long_sourceFileIndex] != '\n' && pchar_sourceFile[long_sourceFileIndex] != '\0'; long_sourceFileIndex++);
                }
            }
        }

        printf("%c",pchar_sourceFile[long_sourceFileIndex]);
     }
 }

참조URL: https://stackoverflow.com/questions/2394017/remove-comments-from-c-c-code

반응형