Volume 9, Number 7 -- February 25, 2009

A Bevy of BIFs: %SCAN and %CHECK

Published: February 25, 2009

by Jon Paris

From recent questions on Internet lists, and from one-on-one discussions with RPG programmers, it seems that many are confused about the usage and operation of a number of built-in functions (BIFs). In particular the BIFs %XLATE, %REPLACE, %SCAN, and %CHECK seem to cause a lot of confusion. In this tip, I focus on %CHECK and %SCAN. I'll look at the other misunderstood pair, XLATE and REPLACE, in a future tip.

The %SCAN BIF has been with us since V3R7, when it was introduced along with %EDITC and %EDITW, to improve string handling. %CHECK, on the other hand, is a relative newcomer, having been introduced in V5R1 to support the functionality of the old CHECK op-code in /Free form coding. As with all BIFs, one of the major advantages compared with the old op-code version is that the BIF can be used directly in a conditional expression--no need to create a temporary work variable and test that.

Here's the syntax definition for our two BIFs:

%CHECK( comparator : base {: startpos})
%SCAN( search argument : source {: startpos})

As you can see the parameters are at first glance very much alike, particularly if like me you tend to mentally convert terms such as "comparator" to "search string". Perhaps this accounts in part for the confusion. But there are two very big differences between these two BIFs.

The first is that with %CHECK, the compare string is treated as a list of individual characters, whereas %SCAN operates on it as a single string. The second is that %SCAN tries to locate an occurrence of the characters in the compare string, whereas %CHECK tries to identify any characters that are not present in the compare string.


Let's review the operation of %CHECK first. This BIF steps through the input a character at a time, comparing each one with the list in the compare string. If it encounters a character that does not exist in the compare set, it returns the position of that character in the input string. In other words, you can think of the compare string as being a list of the characters that are valid in the input field.

For example, a compare string that validates the individual characters in a phone number field might look like this:

'0123456789-( )'

Since %CHECK is a function, it can be used directly in tests such as this one:

If %Check( ' 0123456789-()': character) <> 0;
    // Bad character in phone #

This is useful where the actual position of the "bad" character in the string is not important. In practice I would have coded the string of valid characters as a constant, but I coded the literal in this example for ease of explanation.

%CHECK has a companion BIF, %CHECKR, which works exactly like %CHECK, but backward. In other words, it begins its scan at the right-hand end of the input field. At one time this feature was very useful when dealing with fields that were padded with characters other than spaces. However, the %TRIMx family of BIFs has been updated to allow any specified character to be trimmed, so %CHECKR has less utility than it once did.


Like many RPGers, I used to have problems remembering whether the first parameter to %SCAN was the string I was searching, or the string I was searching for. For me this was resolved by an example from former RPG compiler team member, Hans Boldt. His version of the syntax was:

%SCAN( needle : haystack {: startpos})

I've never had a problem remembering the sequence since!

As we noted earlier, %SCAN is looking for a specific character string. That string can be a single character, or a group of characters. If it finds the requested string in the input (or should I say "haystack"), it returns the position of the first matching character. If it fails to find a match, it returns zero.

When using %SCAN, don't forget that you may need to take spaces into account. For example, when searching for the word "is", you may need to specify it with both a leading and trailing space. If you don't, then words such as "This" and "issue" will also give a positive response--and that may not be what you want.

One last point on %SCAN: If you want to make your scan code as generic as possible, consider using a variable length field (keyword VARYING) for the compare string. That way you won't have to worry about trailing spaces in the string messing up the comparison.

The following brief sample demonstrates this:

D targetFix       s             10a
D targetVar       s             10a   Varying   

D source          s             30a   
D position        s              5i 0


  source = 'this is the test input string';
  targetFix = 'is';
  position = %Scan( targetFix: source); 
    // position value is zero due to trailing spaces
  dsply ('Position of ' + targetFix + ' is ' + %Char(position));

  targetVar = 'is';
  position = %Scan( targetVar: source);  
    // position value is 3
  dsply ('Position of ' + targetVar +  ' is ' + %Char(position)); 

Before I close, I should just touch on the one parameter we haven't mentioned, the start position, which is common to both of these BIFs and works in the same way. It determines the point at which the comparison is to begin. By default the start position is 1, except for %CHECKR, of course, where it is the last character in the input field. This parameter is most commonly used when calling the BIF in a loop, where you need to skip past any instances of the search string that have already been handled. I can't recall ever using it with %CHECK, but I use it often with %SCAN and we will look at an example of such usage when we review the %REPLACE BIF.

BIFs are a vastly underutilized resource in RPG programming. Hopefully this series will help you gain a greater understanding of their utility and help clear up some common misunderstandings.

Jon Paris is one of the world's most knowledgeable experts on programming on the System i platform. Paris cut his teeth on the System/38 way back when, and in 1987 he joined IBM's Toronto software lab to work on the COBOL compilers for the System/38 and System/36. He also worked on the creation of the COBOL/400 compilers for the original AS/400s back in 1988, and was one of the key developers behind RPG IV and the CODE/400 development tool. In 1998, he left IBM to start his own education and training firm, a job he does to this day with his wife, Susan Gantner--also an expert in System i programming. Paris and Gantner, along with Paul Tuohy and Skip Marchesani, are co-founders of System i Developer, which hosts the new RPG & DB2 Summitconference. Send your questions or comments for Jon to Ted Holt via the IT Jungle Contact page.


A Bevy of BIFs: Look Up to %LookUp

A Bevy of BIFs: Getting a Date is Easy with %Date

                     Post this story to del.icio.us
               Post this story to Digg
    Post this story to Slashdot

Sponsored By

When modernizing green-screens, there
are many technologies to choose from. How do
you know which one is right for you?

Is it Java? CGI? PHP? .NET?

How do you know which one will prevail?

Download our free on-demand webinar today
and find out how to pick the right modernization approach.

Register for the FREE webinar today

Senior Technical Editor: Ted Holt
Technical Editor: Joe Hertvik
Contributing Technical Editors: Edwin Earley, Brian Kelly, Michael Sansoterra
Publisher and Advertising Director: Jenny Thomas
Advertising Sales Representative: Kim Reed
Contact the Editors: To contact anyone on the IT Jungle Team
Go to our contacts page and send us a message.

Sponsored Links

WMCPA:  24rd Annual Spring Technical Conference, April 1 & 2, 2009, Delavan, WI
COMMON:  Join us at the 2009 annual meeting and expo, April 26-30, Reno, Nevada
Vision Solutions:  Learn About Data Integration for Business Intelligence


IT Jungle Store Top Book Picks

Easy Steps to Internet Programming for AS/400, iSeries, and System i: List Price, $49.95
Getting Started with PHP for i5/OS: List Price, $59.95
The System i RPG & RPG IV Tutorial and Lab Exercises: List Price, $59.95
The System i Pocket RPG & RPG IV Guide: List Price, $69.95
The iSeries Pocket Database Guide: List Price, $59.00
The iSeries Pocket Developers' Guide: List Price, $59.00
The iSeries Pocket SQL Guide: List Price, $59.00
The iSeries Pocket Query Guide: List Price, $49.00
The iSeries Pocket WebFacing Primer: List Price, $39.00
Migrating to WebSphere Express for iSeries: List Price, $49.00
iSeries Express Web Implementer's Guide: List Price, $59.00
Getting Started with WebSphere Development Studio for iSeries: List Price, $79.95
Getting Started With WebSphere Development Studio Client for iSeries: List Price, $89.00
Getting Started with WebSphere Express for iSeries: List Price, $49.00
WebFacing Application Design and Development Guide: List Price, $55.00
Can the AS/400 Survive IBM?: List Price, $49.00
The All-Everything Machine: List Price, $29.95
Chip Wars: List Price, $29.95

The Four Hundred
Colonizing Endicott

PHP Forges Ahead; Consultant Propels Multiple Projects

i Shops Get Some Power Rewards Action, Finally

As I See It: A Novel Idea

Virtualization Takes Off on Entry Power Systems

Four Hundred Stuff
Speedware Says RPG-to-.NET Code Converter Is the Real Deal

Tripwire Adds i OS Support to Configuration Control Software

Automated Routing Streamlines Deliveries, Lowers Distribution Costs

iEnterprises CRM Goes On-Demand with Help from IBM

iWay Debuts New Information Management Suite

Four Hundred Monitor
Four Hundred Monitor's
Full iSeries Events Calendar

System i PTF Guide
February 21, 2009: Volume 11, Number 8

February 14, 2009: Volume 11, Number 7

February 7, 2009: Volume 11, Number 6

January 31, 2009: Volume 11, Number 5

January 24, 2009: Volume 11, Number 4

January 17, 2009: Volume 11, Number 3

TPM at The Register
Red Hat cranks virtualization power play

Citrix undercuts VMware with XenServer giveaway

Shuttleworth gets cloudy with Ubuntu 9.10

IBM beefs System x with latest Intel, AMD chips

IBM, IBEC do rural Internet broadband

IBM lands 25 teraflop iDataplex cluster in Bluegrass State

HP printer, server, and PC sales in double digit dip

Dell punts green gear with 0% interest

DreamWorks to bake 3D flicks on desert cloud

Voltaire preps InfiniBand switch for IBM blades

Fake server beats real server on Web test

Appro calls Cray ante with super blade cluster

Red Hat and Microsoft ink virt interoperability deal

Intel's future Xeons to share sockets


Profound Logic Software
WorksRight Software
Northeast User Groups Conference

Printer Friendly Version

A Bevy of BIFs: %SCAN and %CHECK

Easily Avoid a Common Data Structure Error

Admin Alert: Robot/SCHEDULE's DST Work-Around and More

Four Hundred Guru


From the IT Jungle Forums
Insert via Java

iSeries Access for Web

Mimix installation and configuration docs

EDI Inovis Programmer - Heavy Duty Problem Solver - Anytime

Data Queues vs. MQ Series: Performance

Removing blanks from a CL Variable


Subscription Information:
You can unsubscribe, change your email address, or sign up for any of IT Jungle's free e-newsletters through our Web site at http://www.itjungle.com/sub/subscribe.html.

Copyright © 1996-2009 Guild Companies, Inc. All Rights Reserved.
Guild Companies, Inc., 50 Park Terrace East, Suite 8F, New York, NY 10034

Privacy Statement