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
그것은 너의 의견이 얼마나 비뚤어져 있느냐에 달려 있다.나는 프로그램이 있다.scc
C와 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 -E
C 컴파일러가 전처리기 단계 후에 멈추라고 하는군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
행동
- 멀티 라인에 걸쳐 있거나 전체 라인을 차지하는 C 스타일 코멘트가 영점 처리된다.
- 줄 가운데에 있는 C 스타일 코멘트는 변함이 없다.예를 들어,
void init(/* do initialization */) {...}
- 전체 라인을 차지하는 C++ 스타일 코멘트가 영점 처리된다.
- 확인을 통해 C 문자열 리터럴이 존중됨
"
그리고\"
. - 직선을 긋다이전 행이 다음으로 끝나는 경우
\
current line 은 laugh atthe dayda. - 줄 번호는 그대로 유지된다.영점 처리된 선 또는 선의 일부가 비어 있음
테스트 & 프로파일링
나는 코멘트가 많은 가장 큰 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
'IT이야기' 카테고리의 다른 글
Nuxt.js 라우팅 URL(대시 제외) / (0) | 2022.04.22 |
---|---|
Vuejs는 데이터가 로드된 후에만 하위 구성 요소를 마운트함 (0) | 2022.04.22 |
vuex 저장소가 변경될 때 프로펠러 속성 업데이트 (0) | 2022.04.22 |
Java Regex 캡처 그룹 (0) | 2022.04.22 |
Threaten, LocalDate를 사용하여 월의 처음 및 마지막 날짜 가져오기 (0) | 2022.04.21 |