This page is a lookup for %check and %checkr: what each returns, the direction each one scans from, and the validation patterns they are normally used for. For the rest of the string functions, see the RPGLE String BIFs Reference. The complete list of BIFs is in the RPGLE Built-in Functions Reference.
All examples are free-form RPGLE. Positions in a string start at 1.
Syntax
%check(comparator : base {: start {: *natural | *stdcharsize}})
%checkr(comparator : base {: start {: *natural | *stdcharsize}})
| Parameter | Meaning |
|---|---|
comparator | The list of allowed characters. Character, graphic or UCS-2 data, fixed or varying |
base | The string to check. Must be the same data type as comparator |
start | Optional. For %check, the first position to examine; defaults to 1. For %checkr, the last position to examine working backwards; defaults to the end of base |
*natural or *stdcharsize | Optional, and must be the last parameter when given. Chooses whether a position counts characters or bytes for multibyte data |
Both functions return a numeric position, or 0 when every character of base (from start onward, in the function’s direction) appears in comparator.
%CHECK: scanning from the left
%check returns the position of the first character in base, from start onward, that is not in comparator.
dcl-s bad int(10);
bad = %check('0123456789' : '12a4'); // 3, the 'a'
bad = %check('0123456789' : '1234'); // 0, all digits
%CHECKR: scanning from the right
%checkr does the same comparison in the opposite direction: it returns the position of the last character in base, working backwards from start, that is not in comparator.
dcl-s bad int(10);
bad = %checkr('0123456789' : '12a4b'); // 5, the 'b', found scanning right to left
bad = %checkr('0123456789' : '1234'); // 0, all digits
When base has more than one character outside comparator, %check and %checkr can return different positions, because each reports the one closest to its own starting end.
dcl-s first int(10);
dcl-s last int(10);
first = %check('0123456789' : 'a12b34'); // 1, the first bad character from the left
last = %checkr('0123456789' : 'a12b34'); // 4, the last bad character from the right
Validating a numeric string
The most common use of %check is confirming that a character field holds only digits (or only digits and a sign) before converting it with %int or %dec, which stop the program on invalid data.
dcl-s input varchar(10) inz('12345');
dcl-s value int(10);
if %len(input) > 0 and %check('0123456789' : input) = 0;
value = %int(input);
else;
value = 0; // reject or default, according to the business rule
endif;
To allow a leading sign or decimal point, add those characters to the comparator list, and decide separately whether a sign is only valid in the first position.
dcl-s amount varchar(12) inz('-123.45');
dcl-s okChars int(10);
okChars = %check('0123456789.-' : amount); // 0 if every character is a digit, '.' or '-'
That check alone does not confirm the sign appears only once or only at the start; it confirms only that no other character is present. For a stricter check, test the first character separately with %subst before calling %check on the remainder.
%CHECK or %CHECKR with a start position
The start parameter limits the scan instead of checking the whole string, which is useful when part of a field is known to be valid.
dcl-s code varchar(12) inz('AB-123456');
dcl-s bad int(10);
bad = %check('0123456789' : code : 4); // scan only from position 4 onward
%CHECK compared with %SCAN
%check and %scan both return a position or 0, but they answer different questions. %scan looks for one specific substring. %check looks for the first character that is outside an allowed set, regardless of what that character is.
| BIF | Answers | Comparator argument |
|---|---|---|
%scan | “Where does this exact substring appear?” | The substring to find |
%check | “Where is the first character not on this list?” | The list of allowed characters |
%checkr | “Where is the last character not on this list?” | The list of allowed characters |
Use %check for validating that a field contains only permitted characters, and %scan for finding a known delimiter or marker.
Worked example: validating a product code
A product code field might allow only uppercase letters, digits and a hyphen. This worked example rejects any code that contains another character, and separately confirms the hyphen is not the first character.
dcl-s productCode varchar(15) inz('AB-12345');
dcl-s firstBad int(10);
dcl-s valid ind;
valid = *on;
firstBad = %check('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-' : productCode);
if firstBad > 0;
valid = *off;
elseif %subst(productCode : 1 : 1) = '-';
valid = *off;
endif;
The %check call alone confirms every character is a letter, a digit or a hyphen; it says nothing about position, so the separate %subst test is needed to catch a leading hyphen. This split, one BIF for membership and one more test for position, is the usual shape of a validation routine built on %check or %checkr.
Multibyte data
Like the other string BIFs, %check and %checkr accept a final optional parameter, *natural or *stdcharsize, which chooses whether a position counts characters or bytes. It only matters for multibyte data such as UTF-8, and the examples on this page use single-byte data and do not need it. For CCSID handling, read the ILE RPG String Handling tutorial.
Common mistakes
- Reversing the arguments:
comparator(the allowed list) comes first,base(the string being checked) comes second. - Treating a non-zero result as an error without checking which character it points to; the position is informational, not only a flag.
- Assuming
%checkvalidates format (such as “digits only, then one decimal point”) rather than only membership in the comparator list. A string like1.2.3passes a comparator of0123456789.even though it is not a valid number. - Forgetting that
comparatorandbasemust be the same data type; a numeric field must be converted to character data before either function is called. - Using
%checkrwhen%checkwas intended. They can return different positions on the same input when more than one invalid character is present.
FAQ
What is the difference between %CHECK and %CHECKR?
%check scans from the start (or from start if given) and returns the first character not in the comparator list. %checkr scans backward from the end (or from start if given) and returns the last one.
How do I check that a field contains only digits?
%check('0123456789' : field) = 0 is true when every character in field is a digit.
Does %CHECK validate a number’s format, such as decimal points or signs?
No. It only confirms that every character is somewhere in the comparator list, not that the characters appear in a valid order or combination.
Related BIFs
- RPGLE String BIFs Reference: the full string family, including
%scanand%xlate. - RPGLE Numeric and Conversion BIFs Reference:
%intand%dec, which stop the program on invalid character data. - RPGLE Built-in Functions Reference: the full index by task.
Summary
%check(comparator : base)finds the first character inbasenot incomparator, scanning from the left;%checkrdoes the same scanning from the right.- Both return 0 when every character is allowed.
- Use
%checkbefore%intor%decto confirm character data is safe to convert.