2016-07-18 2 views
0

이 질문에 대한 답변은 이미 알고 있지만 내 자신의 솔루션이 있으므로이 버그를 해결하고 싶습니다. 나는 따옴표 주석에 대해 걱정하지 않는다. 나는이 코드가 그들을 처리하지 않는다는 것을 안다. 문제는 /* … */ 주석을 시작하는 초기 / 주석이 파일에 인쇄되지 않아야한다는 것입니다.파일에서 주석을 삭제하는 경우

int cleanFile(char *fileName){ 

FILE *fp; 
fp = fopen(fileName, "r"); 
int inComment = 0; 
char current, next; 

//will return exit exicution 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; 
} 
//creat a new file for the clean input 
FILE *cf; 
cf = fopen("cleaninput.txt", "w"); 

current = fgetc(fp); 

while(current != EOF){ 

    if(inComment == 0){ 

     if(current == '/') 
     { 
      next = fgetc(fp); 

       //look ahead and see if this is the start of a comment 
       if(next == '*') 
       { 

        inComment = 1; 
        current = next; //CODE JUMPS FROM HERE 

       }else{ 

        fputc(current, cf); 
        current = next; 

       } 
     }else{ 
      fputc(current, cf); 
      current = fgetc(fp); // AND LANDS HERE 
     } 

    //if an exit sequence is found set in comment to false 
    }else{ 
     if(current == '*') 
     { 
      next = fgetc(fp); 
      if(next == '/') 
      { 
       inComment = 0; 
       current = next; 
      } 
     }else{ 
      current = fgetc(fp); 
     } 
    } 
}//end while 

fclose(fp); 
fclose(cf); 

return 1; 
} 
+0

스크립팅 언어를 사용합니다. – P0W

+0

@ P0W : Python과 같은 높은 추상화 언어를 사용할 수 있지만 스크립팅 언어는 아닙니다. – Olaf

+0

'fgetc()'는'char'가 아니라'int'를 반환합니다. 따라서 '현재'는 'int'이어야합니다. 그렇지 않으면, 당신은 안정적으로 EOF를 탐지 할 수 없지만, 평범한'char' 타입이 서명 된 것이라면, 보통 그것을 피할 수 있습니다. –

답변

0

주석이 여러 줄에 걸쳐 있지 않다고 가정하면 첫 번째 문자가 슬래시로 시작될 때 전체 줄을 무시하면 쉽지 않을까요?

두 번째 IF 문에 문제가있을 수 있다고 판단하여 조건식을 확인하십시오. 읽은 문자가 별표가 아닌 경우 프로그램은 즉시 파일에 기록합니다.

소스 코드에 다음 행이있는 경우.

// Something here 

내 프로그램은이 경우에 슬래시하고 또한 슬래시 아닌 별표 상기 제 2 문자를 판독하고, 첫 번째 문자를 판독한다. 결과적으로 ELSE 문은 대신 프로그램이 전체 행을 무시하지 않고 출력 파일에 쓰도록 실행합니다.

+0

주석은 여러 줄에 걸쳐 있습니다. 주석은'extern int somefunc (int/* arg1 * /, char */* arg2 * /);'와 같이 한 줄에 여러 번 나타날 수 있습니다. 주석을 처리하는 데 어려움이 있다면 다른 사람들의 코드가 여러분을 물으 실 것입니다.사람들은 코드에서 가장 이상하고 가장 짜증나는 일을합니다. 주석 스트리퍼는 잘못 될 여지가 없습니다. –

1

너의 문제는 앞쪽에 /이 인쇄되어 있지만 후행 /이 인쇄되어 있지 않습니다. 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++ 원시 문자열은 또 다른 복잡성 수준입니다.

관련 문제