#include #include #include #include // for isspace() // counts the number of blank lines and // comment lines int main(int argc, char **argv) { FILE *f; // Take the filename from command line argument if (argc != 2) { fprintf(stderr, "usage: %s filename\n", argv[0]); return EXIT_FAILURE; } // Open, read, and print the file f = fopen(argv[1], "r"); if (f == NULL) { fprintf(stderr, "%s -- ", argv[1]); perror("fopen failed"); return EXIT_FAILURE; } // set up state machine typedef enum state_t {START, POSSIBLE_COMMENT, COMMENT, OTHER, NUM_STATES} State; typedef enum linetype_t {BLANK_LINE, COMMENT_LINE, OTHER_LINE, NUM_LINE_TYPES} LineType; State fsaState = START; int count[NUM_LINE_TYPES] = { 0, 0, 0}; char c; while ( (c = fgetc(f)) != EOF ) { switch(fsaState) { case START: if ( c == '\n' ) count[BLANK_LINE]++; else if (isspace(c) ); else if (c == '/') fsaState = POSSIBLE_COMMENT; else { fsaState = OTHER; count[OTHER_LINE]++; } break; case POSSIBLE_COMMENT: if ( c == '/' ) { fsaState = COMMENT; count[COMMENT_LINE]++; } else if (c == '\n') { fsaState = START; count[OTHER_LINE]++; } else { fsaState = OTHER; count[OTHER_LINE]++; } break; case COMMENT: if ( c == '\n' ) fsaState = START; break; case OTHER: if ( c == '\n' ) fsaState = START; break; default: fprintf(stderr, "Internal error\n"); return EXIT_FAILURE; } } fclose(f); printf("Blank lines: %d\n", count[BLANK_LINE]); printf("Comment lines: %d\n", count[COMMENT_LINE]); printf("Other lines: %d\n", count[OTHER_LINE]); return EXIT_SUCCESS; }