2017-01-29 2 views
1

Я написал код, чтобы удалить комментарии из файла программы C, и распечатать вывод на консоль:Удаление комментариев из файла и его печати на консоли

#include <stdio.h> 
#include <stdlib.h> 

void incomment(FILE *fp); 
void rcomment(int c, FILE *fp); 
void echo_quote(int c, FILE *fp); 

int main() { 
    FILE *fp; 
    fp = fopen("temp.c", "r"); 
    int c; 

    while ((c = getc(fp)) != EOF) { 
     rcomment(c, fp); 
    } 
    return 0; 
} 

void incomment(FILE* fp) { 
    int c, d; 
    c = getc(fp); 
    d = getc(fp); 
    while (c != '*' && d != '/') { 
     c = d; 
     d = getc(fp); 
    } 
} 

void echo_quote(int c, FILE *fp) { 
    int d; 
    putchar(c); 
    while ((d = getc(fp)) != c) { 
     putchar(d); 
     if (d == '\\') 
      putchar(getc(fp)); 
    } 
    putchar(d); 
} 

void rcomment(int c, FILE *fp) { 
    int d; 

    if (c == '/') { 
     if ((d = getc(fp)) == '*') 
      incomment(fp); 
     else 
     if (d == '/') { 
      putchar(c); 
      rcomment(d, fp); 
     } else { 
      putchar(c); 
      putchar(d); 
     } 
    } else 
    if (c == '\'' || c == '"') 
     echo_quote(c, fp); 
    else 
     putchar(c); 
} 

Однако для следующего ввода:

#include<stdio.h> 
/* Author : XYZ 
* Date : 21/1/2016 
*/ 
int main() 
{ 
int a; ///variable a 
printf("/*Hi*/"); 
return 0; 
} 

ВЫВОД:

#include<stdio.h> 
Date : 21/1/2016 
*/ 
int main() 
{ 
int a; ///variable a 
printf("/*Hi*/"); 
return 0; 
} 

Может кто-то указать на ошибку в коде. Кажется, он отлично работает для комментариев в кавычках. Но не для комментариев одной строки.

+0

«Может кто-то указать на ошибку в коде». Используйте отладчик, чтобы помочь вам это выяснить. Изучение использования отладчика будет стоить вашего времени и быть более полезным для вас, чем просто отлаживать его для вас. – kaylum

+0

боковой узел: никогда не записывайте дату в этом формате. Это может быть неправильно прочитано, день меньше 32, лучше использовать ISO8601. – 12431234123412341234123

ответ

1

rcomment() функция не анализирует одну строку комментарии правильно:

  • Если сопоставить '/' для второго символа, вы должны прочитать все оставшиеся символы UPTO символ новой строки и вывода только символ новой строки.

  • Если второй символ является цитатой, вы не можете вывести первый символ и проанализировать литерал. Легкий способ сделать это - отключить второй символ с ungetc(d, fp); и вывести только c.

Есть другие специальные случаев вы не обрабатываете:

  • Сбежал новая строка должна быть обработана в литералах и однострочных комментариях, а также в период между / и * в начале многострочный комментарий и между * и / в конце. Вы можете сделать это просто с помощью служебной функции, чтобы читать байты из файла, который обрабатывает экранированные строки новой строки, но будет сложно выводить их обратно в выходной файл, чтобы сохранить количество строк.

  • Вы должны заменить многострочные комментарии одним пробелом или символами новой строки, чтобы избежать вставки жетонов и сохранения количества строк.

  • incomment() и echo_quote() должен обрабатывать преждевременный конец файла. Как в настоящее время кодируются, они работают бесконечно.

Эта задача синтаксического анализа более тонкая, чем кажется. Вы можете попробовать другой подход и реализовать конечный автомат.

Вот быстрое решение для функции rcomment(), но другие вопросы остаются выше:

int peekc(FILE *fp) { 
    int c = getc(fp); 
    if (c != EOF) 
     ungetc(c, fp); 
    return c; 
} 

void rcomment(int c, FILE *fp) { 
    int d; 

    if (c == '/') { 
     if ((d = getc(fp)) == '*') { 
      incomment(fp); 
     } else 
     if (d == '/') { 
      while ((c = getc(fp)) != EOF && c != '\n') { 
       if (c == '\\' && peekc(fp) == '\n') { 
        putchar(getc(fp)); 
       } 
      } 
      putchar('\n'); 
     } else { 
      putchar(c); 
      ungetc(d, fp); 
     } 
    } else 
    if (c == '\'' || c == '"') { 
     echo_quote(c, fp); 
    } else { 
     putchar(c); 
    } 
} 
Смежные вопросы