How can you trim a variable in CLLE??
4 Answers
No standard function TRIM is available in CLLE. However,
- If you want to glue two variables, then look at *TCAT (or |<). This command removes the blanks in between (e.g. 'xyz ' *TCAT 'uvw' becomes 'xyzuvw'
- If you really want to trim, then try '' *TCAT $YOURVAR *TCAT '' (can't try this one myself now. No as/400 around at home ... )
- Or use the fact that you're working with ILE CL. You can use the command CALLPRC to call a module that can do the trick! Write that module yourself with ILE RPG or COBOL.

- 1,014
- 6
- 7
-
If you need, then I can give you a RPG example. RPG is my preferred language on the iSeries. – robertnl Feb 24 '10 at 18:39
-
The \*TCAT strips the trailing blanks of the operand on the left of the operator; the leading blanks of the operand on the right are not stripped :-( Thus the effect of the second example expression [which is not even supported, as coded, per the empty-string disallowed as a string literal, per CPD0126] would match the effect of a TRIMR rather than a TRIM [if first corrected, to use blank literals. And to emphasize that, the first example expression does not *remove the blanks* generally, only removing the one trailing blank from the `'xyz '`. `'xyz ' *TCAT ' uvw'` becomes `'xzy uvw'` – CRPence Oct 05 '16 at 02:39
Since all variables in CL are fixed length, there is no logical requirement to trim per se.
To join two value without intervening spaces, use the |<
operator, and to include a single space use |>
.
To find the length in characters excluding trailing spaces, you need to do a good ol' fashioned walk backwards on the value using %SST(&VAL &POS 1) to test each character position for a space. Something like:
DCL &LEN *DEC (15 0)
DCL &VAL *CHAR 50 VALUE('Some test data')
DCL &CHR15 *CHAR 15
CHGVAR &LEN 50
LOOP: IF (&LEN > 1 & %SST(&VAL &LEN 1)==' ') (DO)
CHGVAR &LEN VALUE(&LEN - 1)
GOTO LOOP
ENDDO
CHGVAR &CHR15 &LEN
SNDPGMMSG ('The length is' |> &CHR15) /* Can't concat decimal values */
To simply null-terminate a value to, for example, make a call to a C function:
DCL &VAL *CHAR 50 VALUE('Some test text')
DCL &VALNUL *CHAR 51 /* +1 for the null */
DCL &NULL *CHAR 1 VALUE(X'00')
CHGVAR &VALNUL VALUE(&VAL |< &NULL)
EDIT 2012-07-19*
In some character sets !
is used instead of |
. There is also the CCSID independent *CAT operation that can be used instead. See IBM's website here and here.

- 63,018
- 25
- 139
- 189
-
In which release where those operators introduced? The operators `|<` and `|>` don't work on our V6R1. Since the character `|` is not on the same position in all EBCDIC Codepages, I don't think it is such a good idea to use those instead of `*TCAT` anyway. – kratenko Jul 16 '12 at 17:25
-
@kratenko: See my edit - they have been there since at least V3, and I would bet since V1. – Lawrence Dol Jul 19 '12 at 18:03
-
The various operators have been around since the System/38 (a predecessor to the AS/400 series). For i 6.1 documentation, see the **Operators in expressions** [Link](http://pic.dhe.ibm.com/infocenter/iseries/v6r1m0/index.jsp?topic=/rbam6/rbam6opsinexp.htm) topic. If they don't work on a given system, the problem is almost guaranteed to be an incorrectly configured device description; the KBDTYPE() and/or CHRID() attributes are probably mismatched with system configuration. – user2338816 Mar 24 '14 at 11:46
-
BTW, the fact that they "don't work" on some systems is the biggest reason not to use them. Changes to the local system or to a given *DEVD can make them not work even if they previously did work. – user2338816 Mar 24 '14 at 11:48
-
@user2338816: Not working can only apply to attempting to compile the source and receiving an error. Once compiled the operators used in the source are irrelevant. That is certainly no reason to avoid using them. – Lawrence Dol Mar 24 '14 at 17:56
-
@Lawrence Dol: "Not work" is intended to mean 'when compiled', as the earlier comment implied. After initial successful compile, a second time it applies is after a second developer later attempts to modify the proc using a different *DEVD with different configuration. The variant character can show up changed. Without a good understanding of what the problem is, it can add troublesome time to what might be a time-sensitive fix. This is even more likely when attempting to deploy source to multiple servers and some can compile while others can't. Developers should consider maintenance. – user2338816 Mar 25 '14 at 01:43
In releases before %TRIM(), %TRIML() and %TRIMR() were available, ILE CL could use the 'triml' C library function:
dcl &lPath *int value( 0 )
callprc 'triml' ( +
&Dir +
( ' ' *byval ) +
) +
rtnval( &lPath )
The proc is found in *SRVPGM QC2UTIL1.
In both OPM and ILE CL, I've often used:
dcl &lmsgtxt1 *dec ( 5 0 ) value( 0 )
rtvmsg msgid( cpf9897 ) msgf( QSYS/QCPFMSG ) +
msgdta( &SQLStm ) +
msglen( &lmsgtxt1 )
In both cases, the resulting length can then be used in a %SST() expression to effect the actual trimming.

- 2,163
- 11
- 11