너의 문제는 앞쪽에 /
이 인쇄되어 있지만 후행 /
이 인쇄되어 있지 않습니다. next
이 /
일 때 대신 을 다음 입력 문자로 설정하여이 문제를 해결할 수 있습니다. 다른 (최소한의) 수정으로
:
#include <stdio.h>
static int cleanFile(char *fileName)
{
FILE *fp;
fp = fopen(fileName, "r");
int inComment = 0;
int current, next;
/* will return exit execution if the file does not exist */
if (fp == NULL)
{
printf("%s", "File was not found.\nFile is expected to be in src directory.");
return 0;
}
/* create a new file for the clean input */
FILE *cf = fopen("cleaninput.txt", "w");
current = fgetc(fp);
while (current != EOF)
{
if (inComment == 0)
{
if (current == '/')
{
next = fgetc(fp);
if (next == EOF)
{
fputc(current, cf);
break;
}
/* look ahead and see if this is the start of a comment */
if (next == '*')
{
inComment = 1;
current = fgetc(fp);
}
else
{
fputc(current, cf);
current = next;
}
}
else
{
fputc(current, cf);
current = fgetc(fp);
}
}
else if (current == '*')
{
next = fgetc(fp);
if (next == '/')
{
inComment = 0;
current = fgetc(fp);
}
else
{
current = next;
}
}
else
{
current = fgetc(fp);
}
}/* end while */
fclose(fp);
fclose(cf);
return 1;
}
int main(int argc, char **argv)
{
char *filename = "cc23.c";
if (argc == 2)
filename = argv[1];
if (cleanFile(filename))
printf("OK\n");
else
printf("Oops!\n");
return 0;
}
하나 사소한 문제는이 프로그램의 의미 (또는 유효 기간)을 변경할 수있는 빈에 댓글을 대체하지 않는다는 것입니다.
int fpeekc(FILE *fp)
{
int c = getc(fp);
if (c != EOF)
ungetc(c, fp);
return c;
}
그것은이 내다 논리를 단순화하는 것입니다 : 그것은 내 자신의 코드 인 경우
나는 다음 문자를 엿볼 수있는 기능을 사용할 수 있습니다. 또한 이미 열려있는 파일 스트림에서 작업하고 지정된 파일 스트림에 쓰는 기능을 다시 디자인 할 것입니다. 코드를보다 일반적으로 만듭니다.
#include <assert.h>
#include <stdio.h>
/*
* This is adequate for routine comments.
* It wouldn't spot /\
* * as the start of a comment, or *\
*/as the end of a comment (where the " * " line prefix should be ignored).
*/
static int fpeekc(FILE *fp)
{
int c = getc(fp);
if (c != EOF)
ungetc(c, fp);
return c;
}
static void cleanFile(FILE *fin, FILE *fout)
{
int inComment = 0;
int current, next;
while ((current = getc(fin)) != EOF)
{
if (inComment == 0)
{
if (current == '/' && fpeekc(fin) == '*')
{
next = getc(fin);
assert(next == '*');
inComment = 1;
}
else
putc(current, fout);
}
else if (current == '*' && fpeekc(fin) == '/')
{
inComment = 0;
next = fgetc(fin);
assert(next == '/');
}
/* else do not echo comment characters */
}
}
int main(int argc, char **argv)
{
char *filename = "cc29.c";
if (argc == 2)
filename = argv[1];
FILE *fp = fopen(filename, "r");
if (fp == NULL)
{
fprintf(stderr, "Failed to open file %s for reading\n", filename);
return 1;
}
cleanFile(fp, stdout);
return 0;
}
백 슬래시 - 개행 조합은 주석 처리를 복잡하게 - 당신이 C 프리 프로세서를 쓰는 경우가 아니라면 다행히, 당신은 아마 그들에 대해 걱정할 필요가 없습니다. 문자 문자열 및 복수 문자 리터럴 (예 : '/*'
)에 대해 걱정해야합니다. 후자는 이식 가능하지 않지만 그래도 유효하며 주석을 시작하지 마십시오. 그리고 C++ 원시 문자열은 또 다른 복잡성 수준입니다.
스크립팅 언어를 사용합니다. – P0W
@ P0W : Python과 같은 높은 추상화 언어를 사용할 수 있지만 스크립팅 언어는 아닙니다. – Olaf
'fgetc()'는'char'가 아니라'int'를 반환합니다. 따라서 '현재'는 'int'이어야합니다. 그렇지 않으면, 당신은 안정적으로 EOF를 탐지 할 수 없지만, 평범한'char' 타입이 서명 된 것이라면, 보통 그것을 피할 수 있습니다. –