Progtwig C que elimina comentarios.

Esta fue la primera vez que publiqué, así que pido disculpas por el formato deficiente o por cualquier pregunta no razonable.

Así que he estado trabajando en el progtwig “eliminar comentarios” durante algún tiempo y progresé, pero muy mínimo. Soy nuevo en C, así que lo escribo con algunas funciones y habilidades básicas. El archivo de entrada para el código no requiere que se lea ninguna función, sino que se pasa al progtwig usando <en el terminal.

El archivo de texto que estoy usando contiene lo siguiente:

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

Para probar los diferentes formatos de comentario. El código que tengo hasta ahora es:

 #include  #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; } 

La cosa es que no puedo encontrar una manera de configurar una condición que imprima un mensaje de error cuando hay un caso en el que el comentario se inicia pero nunca se cierra, como (algunas / * locuras)

Otro problema es que parece que no puedo encontrar el error que, cuando ejecuto mi progtwig y escribo el archivo de texto, omite el *, así que cuando ingrese:

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

Terminé obteniendo lo siguiente: algunas * cosas

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

No puedo encontrar una manera de solucionar los dos problemas. El profesor sugirió una forma diferente de escribir el progtwig definiendo diferentes estados, pero cuando lo intenté fue aún más confuso.

Su descripción se centra en la diferencia entre operar en un flujo y operar en un búfer. Tanto en C como en Java es posible cualquier técnica.

Aquí su tarea es hacer el trabajo en una situación de transmisión, es decir, no puede “mirar hacia adelante” y no puede “escribir hacia atrás”; todo lo que puede hacer es recuperar el siguiente carácter, actualizar algunas variables si corresponde y decidir si desea o no dar salida a ese personaje.

Esto se llama una máquina de estado ; su bucle principal leerá un carácter y luego tomará una acción diferente según el estado en que se encontraban sus variables.

Para comenzar, necesitará almacenar al menos lo siguiente:

  • Si estás en un comentario o no
  • Si no estás en un comentario, entonces si acabas de leer un / .

Por ejemplo, si se establece el último estado y obtiene un '*' entonces establecerá el estado anterior (y restablecerá el último).

Bueno, la solución habitual para este tipo de problema es hacer FSM . Entonces, solo haga el número de estados y defina cómo cada próxima letra afectará al estado, debido al estado actual. Algo como

 //#define _CRT_SECURE_NO_WARNINGS #include  #include  //#include  #include  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(); } 

este código solo borra / ** /. Escribe un diagtwig más grande y completa el código.

 #include  #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; }