I am sure I am not the only person who has been using the Trim built in functions (BIFs) in their RPG code to remove leading and trailing blanks from strings. Trim BIFs were introduced into CL with IBM i release 7.1, and function in the same way as their RPG brethren.

Were you aware that the Trim BIFs have a second parameter that can be used for removing characters other than blanks? I have Miguel Cordova to thank for bringing this to my attention. Using the second parameter I can remove any character using the Trim. Below I will show examples in RPG and in CL, and discuss what I found in using them in both languages.

The syntax for the RPG and CL BIFs are almost identical, the only difference being the use of the colon ( : ) to separate the two parameters in RPG.

I have used Trim ( %TRIM ), Trim Right ( %TRIMR ), and Trim Left ( %TRIML ) in my RPG code to remove leading and trailing spaces from fields I would be concatenating together:

FullName = %trimr(FirstName) + ' ' + %trimr(LastName) ;

The equivalent in CL could be the following:

CHGVAR VAR(&FULLNAME) VALUE(%TRIMR(&FIRSTNAME) || + ' ' || %TRIMR(&LASTNAME))

Note: In CL I use the shortcuts || and |< in place of *CAT and *TCAT .

So what of this second parameter? If I am presented with a variable that contains a leading or trailing character, for example an asterisk ( * ), I want remove them and left justify the remainder of the string.

01 FirstName = '********John********' ; 02 LastName = '*********Doe********' ; 03 FullName = %trim(FirstName:'*') + ' ' + %trim(LastName:'*') ;

The RPG code above shows that I have my first name in the variable FirstName, line 1, and my last name in LastName, line 2, both with leading and trailing asterisks.

As I have mentioned The Trim BIF ( %TRIM , %TRIMR , %TRIML ) has two parameters:

Name of variable or alphanumeric string.

Characters to replace. The default is blank, which is why we do not have give the second parameter if we are removing blanks.

In the example I have given above I want to remove all leading and trailing asterisks and then concatenate the two variables together into the variable FullName. The result is ' John Doe '.

The equivalent in CL could look like:

01 CHGVAR VAR(&FIRSTNAME) VALUE('********John********') 02 CHGVAR VAR(&LASTNAME) VALUE('*********Doe********') 03 CHGVAR VAR(&FULLNAME) VALUE(%TRIM(&FIRSTNAME '*') || + ' ' || %TRIM(&LASTNAME '*'))

If I replace the first asterisk in the FirstName variable, see below, with a blank when the code is run the variable FullName will contain ' *******John Doe '.

01 FirstName = ' *******John********' ; 02 LastName = '*********Doe*********' ; 03 FullName = %trim(FirstName:'*') + ' ' + %trim(LastName:'*') ;

The reason is that the second parameter of the BIF, 'Characters to replace', does not contain blank. If I add blank to the second parameters of the %TRIM BIFs on line 3, see below, then FullName will contain ' John Doe '.

01 FirstName = ' *******John********' ; 02 LastName = '*********Doe*********' ; 03 FullName = %trim(FirstName:'* ') + ' ' + %trim(LastName:'* ') ;

The same applies if I would have replaced the last character in either FirstName or LastName with a blank.

I could make it really complicated (ridiculous) with a strings like this:

01 dcl-c InvalidCharacters ' ~!@#$%¢&*()_+{}|?' ; 02 FirstName = '!@#$%¢&John*()_+{}|?' ; 03 LastName = '?|}{+_)(*Doe&¢%$#@!~' ; 04 FullName = %trim(FirstName:'~!@#$%¢&*()_+{}|? ') + ' ' + %trim(LastName:InvalidCharacters) ;

You will notice on line 1 that I have defined a constant to contain a whole load of characters I would want to trim from my string. And on line 4 you can see that I have entered all the characters in the %TRIM for FirstName and use the constant with LastName.

In CL the equivalent could be:

01 DCL VAR(&INVALID) TYPE(*CHAR) LEN(20) + VALUE('~!@#$%¢&*()_+{}|? ') 02 CHGVAR VAR(&FIRSTNAME) VALUE('!@#$%¢&*John()_+{}|?~') 03 CHGVAR VAR(&LASTNAME) VALUE('~!@#$%¢&*Doe()_+{}|? ') 04 CHGVAR VAR(&FULLNAME) + VALUE(%TRIM(&FIRSTNAME &INVALID) + || ' ' || %TRIM(&LASTNAME &INVALID))

You can learn more about these on the IBM website:

This article was written for IBM i 7.2, and it should work the 7.1 too.