const blank = ' '; type pac80 = packed array [1..80] of char; {---------------------------------------------------} function trim ( buf : pac80; var f_width : integer) : pac80; {trim takes the 80-byte array passed and physically trims } {the leading blanks off (by left-shifting the text), and } {logically trims any trailing blanks. The resulting width} {is returned in "f_width". } { } {Example: trim (' cat ', W); } { returns: 'cat ', and W = 3 } { } {Note: in left-shifting, the "new" characters at the end } {of the buffer will be blanks. } const max_inx = sizeof (buf); var first_inx: integer; {index of first non-blank in buf} last_inx : integer; {index of last non-blank in buf} inx : integer; {used to index in buf/new_buf} new_buf : pac80; {will hold left-shifted text} width : integer; {length of "trimmed" text} begin {Find first non-blank character in buf...} first_inx := 1; while (first_inx <= max_inx) and (buf [first_inx] = blank) do first_inx := first_inx + 1; {Continue only if we found a non-blank.. .} {Note that if the first non-blank is the } {first character, then we don't need to } {"shift" the text, so we can do a high- } {speed copying of the data in buf to trim's } {functional result. } if first_inx > max_inx then begin {buf is entirely blank} trim := ' '; {pass back a blank buffer} width := 0; {0 -> no non-blank text!} end else begin {must copy data to new_buf} {First, determine width...} {Note that we can avoid a complex while} {condition because we know that we'll } {find a non-blank before last_inx hits 0. } last_inx := max_inx; while buf [last_inx] = ' ' do last_inx := last_inx - 1; width := (last_inx - first_inx) + 1; {Copy the data to new_buf...} {Note that since the "for" below might not} {copy max_inx chars, we need to make sure } {that the trailing part of new_buf is } {blanked out ... to be nice to the caller.} {This could be omitted if the definition } {of "trim" made it clear that the trailing} {data should be undefined. } {(See commentary for alternative) } if width < max_inx then new_buf := ' '; {blank out entire new_buf} for inx := 1 to width do new_buf [inx] := buf [inx + (first_inx - 1)]; trim := new_buf; end; f_width := width; {tell caller the width} end {trim proc};Notes:
On the other hand, the *human* time to understand the new_buf := ' ' is significantly less than to understand an additional FOR loop. Remember to ask: will it take more time to write faster code than will ever be saved by that new code?
Still, here's the FOR loop code...replace the "new_buf := ' ';" with:
{Blank out tail end} for inx := width + 1 to max_inx do new_buf [inx] := ' ';
In general, I avoid accessing simple by-reference parameters via this technique.
(Click here to go back to the commented bad version.)
(Click here to go back to the uncommented
bad version.)
(Click here for the "How To Code Pascal" paper.)