// no-comment.c // Řešení IJC-DU1, příklad b), 22.3.2024 // Autor: Roman Nečas, FIT // Přeloženo: gcc 13.2.1 #include #include "error.h" int main(int argc, char *argv[]) { FILE *fp; int state = 0; int c; int lastChar = 0; // To keep track of the last character to handle line continuation in comments if (argc > 2) { error_exit("Too many arguments"); } if(argc == 2) { fp = fopen(argv[1], "r"); if (!fp) { error_exit("Cannot open file: %s", argv[1]); } } else { fp = stdin; } while ((c = fgetc(fp)) != EOF) { switch (state) { case 0: // Normal code if (c == '/') { state = 1; // Possible comment start } else if (c == '"') { putchar(c); state = 4; // String literal start } else if (c == '\'') // Handle single quotes { putchar(c); state = 7; // Character literal start } else { putchar(c); } break; case 1: // After first '/' if (c == '*') { state = 2; // Multi-line comment start } else if (c == '/') { // Transition to single-line comment state but do not output '/' state = 6; // Single-line comment start } else { putchar('/'); // Not a comment, print '/' and current char putchar(c); state = 0; } break; case 2: // Inside multi-line comment if (c == '*') { state = 3; // Possible end of comment } break; case 3: // Possible end of multi-line comment if (c == '/') { state = 0; // End of comment } else if (c != '*') { state = 2; // Still inside comment } break; case 4: // Inside string literal if (c == '\\') { putchar(c); c = fgetc(fp); // Read next character putchar(c); // Print escaped character // Do not change state, stay in string literal } else if (c == '"') { putchar(c); // End of string literal state = 0; } else { putchar(c); // Part of string literal } break; case 5: // After escape character in string literal putchar(c); // Print escaped character state = 4; break; case 6: // Inside single-line comment if (c == '\n') { if (lastChar != '\\') // If not a continuation { putchar(c); // Ensure newline is outputted to maintain original structure state = 0; // End of single-line comment } // If it was a continuation, simply ignore and continue in state 6 } break; case 7: // Inside character literal putchar(c); if (c == '\\') { state = 8; // Escape sequence within character literal } else if (c == '\'') { state = 0; // End of character literal } break; case 8: // After escape character in character literal putchar(c); // Print escaped character state = 7; // Return to character literal state break; } lastChar = c; // Update lastChar at the end of the loop } if (ferror(fp)) { error_exit("Read error\n"); } if (state != 0) { error_exit("Unterminated comment or string\n"); } fclose(fp); return 0; }