2014-09-16 16 views
0

Это была моя первая публикация, поэтому я извиняюсь за плохой формат и любые необоснованные вопросы.C программа, которая удаляет комментарии

Так что я некоторое время работал над программой «удалить комментарии» и добился прогресса, но очень минимален. Я новичок в C, поэтому я пишу его, используя некоторые основные функции и навыки. Входной файл для кода не требует каких-либо функций для чтения, а вместо этого передается в программу с использованием < в терминале.

Текстовый файл, который я использую содержит следующее:

some/* crazy */stuff 
some/* crazy */ stuff 
some/*crazy /*crazy*/*/stuff 
"some /* crazy */ stuff " 
some/* "crazy" */ stuff 
some/* crazy stuff 

Чтобы проверить различные форматы комментариев. код я до сих пор является:

#include <stdio.h> 
#define IN_COMMENT 1 

int main(int argc, char **argv) 
{ 
    int c; 

    while ((c=getchar())!=EOF) 
    { 
     if(c=='/'&&getchar()=='*') 
     { 
      while(c!='*' && getchar()!='/') 
      { 
       c = " "; 
       c= getchar(); 

      } 

     } 


     if(c=='"') 
     { 
      c=getchar(); 
      while(c!='"') 
      { 
       putchar(c); 
       c=getchar(); 
      } 
      putchar(c); 
     } 
    } 
putchar(c); 
    printf("done.\n"); 
    return 0; 
} 

Дело в том, что я не могу понять способ установить условие, которое будет распечатать сообщение об ошибке, когда есть случай, в котором запускается комментарий, но никогда не закрывался, такие как (некоторые/* сумасшедшие вещи)

Другая проблема заключается в том, что я не могу показаться, чтобы найти ошибку, которая при запуске программы и ввести текстовый файл опускает *, поэтому, когда я ввод:

some/* crazy */stuff 
some/* crazy */ stuff 
some/*crazy /*crazy*/*/stuff 
"some /* crazy */ stuff " 
some/* "crazy" */ stuff 

В конечном итоге я получаю следующее: некоторые * материал

some* stuff 

some**/tuff 

"some /* crazy */ stuff " 

some* stuff 

Я не могу понять способ исправить эти два вопроса. Профессор предложил другой способ написания программы, определив разные состояния, но когда я попытался, это было еще более запутанным.

+4

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

+2

Переменная 'c' является' int', и все же вы выполняете следующее назначение: 'c =" ";' которые присваивают * указателю * c'. Я думаю, вы хотите сделать это, например. 'c = '';'? –

+0

Java развивается из 'C', поэтому индексирование, такое как [1] ​​и [i], полностью действует в' C'. – Abhi

ответ

0

Ваше описание сосредоточено на различии между работой на потоке и работой на буфере. Как в C, так и в Java возможно использование любой из этих технологий.

Здесь ваша задача - выполнить задание в потоковой ситуации, то есть вы не можете «смотреть вперед», и вы не можете «писать назад» - все, что вы можете сделать, это получить следующий символ, обновить некоторые переменные, если это необходимо, и решить выводить этот символ или нет.

Это называется государственная машина; ваш главный цикл будет считывать символ, а затем принимать различные действия на основе, в каком состоянии ваши переменные были в

Для начала, вы будете нуждаться, чтобы сохранить по крайней мере, следующее:.

  • ли вы находитесь в комментарии или нет
  • Если вы не в курсе, то читаете ли вы только /.

Например, если последнее состояние установлено, и вы получаете '*', вы должны установить прежнее состояние (и сбросить последнее).

0

Ну, обычное решение этой проблемы состоит в том, чтобы сделать FSM. Итак, просто введите количество состояний и определите, как каждая следующая буква будет влиять на состояние из-за текущего состояния.Smth как

//#define _CRT_SECURE_NO_WARNINGS 
#include <stdio.h> 
#include <stdlib.h> 
//#include <conio.h> 
#include <string.h> 

typedef enum states { 
    CODE, 
    HASH_START, 
    STAR_END, 
    COMMENT 
} states; 

void main() { 
    FILE *input = NULL; 
    char c; 
    states state; 

    state = CODE; 
    input = fopen("C:/c/code.txt", "r"); 
    if (input == NULL) { 
     exit(EXIT_FAILURE); 
    } 

    while (fscanf(input, "%c", &c) == 1) { 
     switch (c) { 
     case '/' : 
      switch (state) { 
      case CODE: 
       state = HASH_START; 
       break; 
      case STAR_END: 
       //a bit ugly here, but require less states. You can omit read next 
       //if use more states 
       fscanf(input, "%c", &c); 
       state = CODE; 
       break; 
      } 
      break; 
     case '*' : 
      switch (state) { 
      case HASH_START: 
       state = COMMENT; 
       break; 
      case COMMENT: 
       state = STAR_END; 
       break; 
      } 
      break; 
     default: 
      if (state == HASH_START) { 
       state = CODE; 
      } 
     } 
     if (state == CODE) { 
      printf("%c", c); 
     } 
    } 

    //_getch(); 
} 

этот код удаляет только/** /. Напишите большую диаграмму и полный код.

0
#include <stdio.h> 

#if 0 
Description : 
To delete a comment by entering the C source from standard input. 
// To delete a line break up (newline remain) 
/**/ To allow the nest (standard does not allow) 
also replaced with a single space(The request by the standard) 
#endif 

int main(void){ 
    FILE *fp = stdin; 
    int ch, chn; 
    int nest_level=0; 
#if 0 
in_range_comment : /* this */ 
in_line_comment : //this 
in_string : "this" 
in_char_constnt : ' ' 
#endif 
    enum { none, in_line_comment, in_range_comment, in_string, in_char_constant } status; 

    status = none; 
    while(EOF!=(ch=fgetc(fp))){ 
     switch(status){ 
     case in_line_comment : 
      if(ch == '\n'){ 
       status = none; 
       putchar(ch); 
      } 
      continue; 
     case in_range_comment : 
      if(ch == '*'){ 
       chn = fgetc(fp); 
       if(chn == '/'){ 
        if(--nest_level == 0){ 
         status = none; 
         putchar(' '); 
        } 
        continue; 
       } 
       ungetc(chn, fp); 
      } else if(ch == '/'){ 
       chn = fgetc(fp); 
       if(chn == '*'){ 
        ++nest_level; 
        continue; 
       } 
       ungetc(chn, fp); 
      } 
      continue; 
     case in_string : 
      if(ch == '\\'){ 
       putchar(ch); 
       chn = fgetc(fp); 
       if(chn == '"'){ 
        putchar(chn); 
        continue; 
       } 
       ungetc(chn, fp); 
      } else { 
       if(ch == '"') 
        status = none; 
       putchar(ch); 
      } 
      continue; 
     case in_char_constant : 
      if(ch == '\\'){ 
       putchar(ch); 
       chn = fgetc(fp); 
       if(chn == '\''){ 
        putchar(chn); 
        continue; 
       } 
       ungetc(chn, fp); 
      } else { 
       if(ch == '\'') 
        status = none; 
       putchar(ch); 
      } 
      continue; 
     case none : 
      switch(ch){ 
      case '/': 
       if('/' == (chn = fgetc(fp))){ 
        status = in_line_comment; 
        continue; 
       } else if('*' == chn){ 
        status = in_range_comment; 
        ++nest_level; 
        continue; 
       } else 
        ungetc(chn, fp); 
       putchar(ch); 
       break; 
      case '"': 
       status = in_string; 
       putchar(ch); 
       break; 
      case '\'': 
       status = in_char_constant; 
       putchar(ch); 
       break; 
      default: 
       putchar(ch); 
      } 
     } 
    } 

    return 0; 
}