/* EXERCISE 1-22 */ /* RULES: - FOLD WHITESPACE BUT REMOVE BLANK LINES. */ /* - FOR WORDS LONGER THAN N CHARS, BEGIN A NEW LINE */ /* AND FOLD ACROSS MULTIPLE LINES, IF NECESSARY. */ /* - KEEP I/O TO A MINIMUM. */ #include <stdio.h> #define MAXLINE 45 /* A SMALL NUMBER FOR TESTING */ #define TABNO 8 /* TAB SKIPS THIS MANY POSITIONS */ #define YES 1 #define NO 0 int c, i; int wordsave; int prtcnt, wordcnt, blankcnt; char word[MAXLINE]; void linebrk(void); void blnkchar(void); void prtblank(void); void prtword(void); void nonblank(void); main() { wordsave = NO; prtcnt = wordcnt = blankcnt = 0; while ((c = getchar()) != EOF) if (c == '\n') linebrk(); else if (c == ' ' || c == '\t') blnkchar(); else nonblank(); /* HANDLE END-OF-DATA AS A LINE BREAK */ linebrk(); printf("\nEND OF PROGRAM\n"); return 0; } /* LINEBRK: RESET LINE CHAR COUNTER */ void linebrk(void) { if (wordsave == YES) { if (blankcnt > 0) prtblank(); prtword(); } if (prtcnt > 0) putchar('\n'); wordsave = NO; prtcnt = wordcnt = blankcnt = 0; } /* BLNKCHAR: THE NEXT CHARACTER IS BLANK OR TAB */ /* FIRST PRINT OUT THE LAST WORD AND PRECEDING BLANKS */ /* BREAK THE LINE AND REDUCE BLANK COUNT, IF NEW BLANKS */ /* EXCEED LINE LIMIT */ void blnkchar(void) { int newcnt; if (wordsave == YES) { if (blankcnt > 0) prtblank(); prtword(); } wordcnt = 0; if (c == '\t') { /* DETERMINE HOW MANY BLANKS WERE TABBED */ newcnt = TABNO * ((prtcnt + blankcnt) / TABNO + 1); if (newcnt > MAXLINE) newcnt = MAXLINE; /* TABS DO NOT EXCEED THE LINE */ } else newcnt = prtcnt + blankcnt + 1; if (newcnt >= MAXLINE) { if (prtcnt > 0) { putchar('\n'); prtcnt = 0; } blankcnt = newcnt - MAXLINE; } else blankcnt = newcnt - prtcnt; } /* PRTBLANK: PRINT TABS AND BLANKS TO FILL A GIVEN WHITESPACE */ void prtblank(void) { int tabs, newcnt; newcnt = prtcnt + blankcnt; tabs = (newcnt / TABNO) - (prtcnt / TABNO); if (tabs > 0) { blankcnt = newcnt - TABNO * (newcnt / TABNO); while (tabs > 0) { putchar('\t'); --tabs; } } while (blankcnt > 0) { putchar(' '); --blankcnt; } prtcnt = newcnt; } /* PRTWORD: PRINT A WORD FROM THE ARRAY. */ void prtword(void) { if ((prtcnt + wordcnt) > MAXLINE) { if (prtcnt > 0) { putchar('\n'); prtcnt = 0; } } for (i = 0; i < wordcnt; ++i) putchar(word[i]); prtcnt = prtcnt + wordcnt; if (prtcnt >= MAXLINE) { putchar('\n'); prtcnt = 0; } wordsave = NO; } /* NONBLANK: THE NEXT CHARACTER IS NON-BLANK. */ /* COLLECT THEM IN THE WORD ARRAY. */ void nonblank(void) { if (wordcnt < MAXLINE) { wordsave = YES; word[wordcnt] = c; ++wordcnt; } else { if (wordsave == YES) { if (blankcnt > 0) prtblank(); prtword(); } if (prtcnt >= MAXLINE) { putchar('\n'); prtcnt = 0; } putchar(c); ++prtcnt; } }