/* Homework 3 for Allen Holub's C for Professionals class. September, 1990. * By Ronald E. Jacobs. * Revised October 1, 1990: Uses pointers now, no array indexes. Also cosmetic * changes and comments revised. * * adjust(str, col) * * STR is a null terminated string of characters. A word is any * group of characters not separated by a space. Spaces trailing a * word are treated as part of that word. Spaces leading the first * word are treated as part of the first word. Adjust distributes * additional spaces as evenly as is possible between words and * without regard to original spacing, so that the last character * of the last word ends in column COL. If spaces cannot be added * equally between words then the modulo of excess spaces is added, * one space each, between words from the left end of STR until the * excess is exhausted. The string is modified in place. If STR * contains no words or one word, ADJUST does nothing. ADJUST * prints an error message if COL is less than the number of * characters in STR. * * To compile debugging statements: cc -Ddebug adjust.c */ #include #include int nchar; /* Number of characters in original string */ int nword; /* Number of words */ int inword; /* True if pointer is in a word, false if whitespace */ int gap[75]; /* Hold the location of start of each gap */ adjust(str, col) char str[]; int col; { printf("\n 1 2 3"); printf("\ncolumn: 123456789012345678901234567890"); printf("\ninput: "); puts(str); /* print unmodified string */ cntwords(str); /* count characters and words and locate gaps */ fixstr(str, col); /* adjust the string in place */ printf("output: "); puts(str); /* print modified string */ return; } /* * Count the number of characters and words in the string str. * Put into gap[] the character position number following the end of each * word. */ cntwords(str) char str[]; { char *pstr; /* Pointer to character string */ nchar = nword = inword = 0; for(pstr = str; *pstr; ++pstr) { if(*pstr == ' ') { inword = 0; } else if(!inword) { inword = 1; ++nword; if(nword >= 2) { gap[nword-2] = nchar; #ifdef debug printf("\ncharacter count is: %-4u for array subscript %-4u", gap[nword - 2], nword - 2); #endif } } } #ifdef debug printf("\ntotal character count is: %-4u \n", nchar); printf("\nword count is: %-4u ", nword); #endif return; } /*----------------------------------------------------------------*/ fixstr(str, col) char str[]; int col; { /* Do in place adjustment of string */ int wholsp, modsp, nsp, i; int spadded, curgap, nspace, gaps; if(col < nchar) { printf("\nadjust error: more characters than columns"); return; } if(nword < 2) { return; /* no adjustment necessary */ } gaps = (nword - 1); /* number of gaps between words */ wholsp = (col - nchar)/(gaps); /* number of spaces to add per gap */ modsp = col - nchar - gaps * wholsp; /* remainder of spaces to add in gaps */ #ifdef debug printf("\nnumber of gaps is: %-4u ", gaps); printf("\nspaces to add per gap is: %-4u ", wholsp); printf("\nremainder of spaces to add in gaps is: %-4u ", modsp); #endif spadded = 0; /* number of spaces added in previous gaps */ for (i = 0 ; i < gaps; ++i) { nspace = wholsp; if (modsp) { ++nspace; /* spaces to add in this gap */ --modsp; /* remaining remainder spaces */ } curgap = gap[i] + spadded; /* location of current gap*/ spadded += nspace; /* location of next gap after adjusting this gap */ #ifdef debug printf("\nthis gap is number: %-4u ", i); printf("\ncurrent gap location is: %-4u ", curgap); printf("\nnumber of spaces to add in this gap is: %-4u ", nspace); #endif for ( ;nspace; --nspace) { addsp(str, curgap); /* insert a single space */ } } return; } /*--------------------------------------------------------------------*/ addsp(str, curgap) char str[]; int curgap; { /* * Add a ' ' into a null terminated array. Put the ' ' into position * array[charnum] and shift all bytes from the original byte at * array[charnum] up to and including the null termination right one * byte. */ char temp1, temp2; temp1 = ' '; for ( ; ; ) { temp2 = str[curgap]; /* temporarily save current character */ str[curgap] = temp1; /* put old character in new position. */ if (!temp1) /* if character is a null */ { break; } ++curgap; /* work on next character in string */ temp1 = temp2; /* was current character, now old */ } return; }