/******************************************************************** * * CSE 271 Programming Assignment #2 * * Brian D. Davison * Last revised 9 Feb 2005 * * A simple character filter to compress a text sequence. * ********************************************************************/ #include #include const int STDIN = 0; // outputchar() ////////////////////////////////////////////////// // // Output a single character, duplicating escape if needed // Errors cause program to exit. // Assumes never called with ~ more than twice in a row // void outputchar(char c) { int result; if (c == '~') // need to send escape result = printf("~~"); else result = printf("%c", c); if (result < 0) { // failed to write perror("Write failure in outputchar"); exit(-1); } } // outputseq() ////////////////////////////////////////////////// // // Outputs the compressed version of num copies of c // Output errors cause program to exit. // Assumes that next output character will be different from c // void outputseq(char c, int num) { int result; if (num==1) outputchar(c); else if (num==2) { outputchar(c); outputchar(c); } else // print compressed output while (num) { // only allow compression of 9 at a time int t = num > 9 ? 9 : num; result = printf("~%d%c", t, c); if (result < 0) { // failed to write perror("Write failure in outputseq"); exit(-1); } num -= t; } fflush(stdout); } // main() //////////////////////////////////////////////////////////// // // main() reads from standard input until there is no more to read. // Keeps track of how many times a character has been read. When // the next character is different, it outputs the compressed sequence // for the previous character. // int main(void) { char c, oldc = 0; int count = 0; int result; // I'm using read here, but others, such as getchar() should work while ((result = read(STDIN, &c, 1)) == 1) { if (c == oldc) count++; else { if (oldc) { outputseq(oldc, count); } count = 1; oldc = c; } } if (result < -1) { perror("read failure"); exit(-1); } if (count) // if input was non-empty outputseq(oldc, count); return 0; }