There are a number of shortcomings using DISPL, such as the message to display can be maximum 52 characters.
Further, you have to press [ENTER] for each line (which might be what you need in some situations). There is a method to circumvent these short comings, and that is what this article is about.
In stead of using DISPL, you can use two C functions to display messages and to get input from the user.
To display a message on the screen, you use the C function ‘puts’ (put string). It writes out a string on the screen (to standard out to be precise). To write a message containing a numeric or date field, you must convert the number/date to character, e.g. by using the %Char() BIF.
One huge advantage of using ‘puts’ is, that on the terminal screen, you can press [F6] to print everything that has been written to the screen.
The declaration for ‘puts’ is quite simple:
Dcl-PR PutS Int(10:0) ExtProc('puts'); oString Pointer Options(*String) Value; End-PR;
You can now display a message simply by passing the message to PutS:
PutS('Hello world');
To get input from the user, you use the C function ‘gets’ (get string). It returns a string. The declaration for ‘gets’ is:
Dcl-PR GetS Pointer ExtProc('gets'); Buffer Char(1024); End-PR;
‘gets’ returns a zero terminated string. To get a useful character field you can either use %Scan() to locate the x’00’ character or you can simply define a pointer to the character field that ‘gets’ returns, and then use the %Str() BIF to get the characters. The example below shows how to do that.
**Free Ctl-Opt BndDir('QC2LE'); Dcl-PR PutS Int(10:0) ExtProc('puts'); oString Pointer Options(*String) Value; End-PR; Dcl-PR GetS Pointer ExtProc('gets'); Buffer Char(1024); End-PR; Dcl-S InputString Char(1024); Dcl-S pInputString Pointer Inz(%Addr(InputString)); Dcl-S OutputString VarChar(1024); PutS('Hello world. How are you?'); If GetS(InputString) = *Null; // An error occurred PutS('Something went wrong when getting input.'); EndIf; // Get all characters up to, not including the x'00' char. OutputString = %Str(pInputString); PutS('You wrote: ' + OutputString); *InLr = *On; Return;
You could, of cause, wrap ‘gets’ in a procedure to make it very simple to use:
Dcl-Proc GetInput; Dcl-PI GetInput Char(1024); End-PI; // Local work fields. Dcl-S InputString Char(1024); Dcl-S pInputString Pointer Inz(%Addr(InputString)); Dcl-S OutputString VarChar(1024); If GetS(InputString) = *Null; // An error occurred PutS('Something went wrong when getting input.'); Else; // Get all characters up to, not including the x'00' char. OutputString = %Str(pInputString); EndIf; Return OutputString; End-Proc;
Now the example program looks like this:
**Free Ctl-Opt BndDir('QC2LE'); Dcl-PR PutS Int(10:0) ExtProc('puts'); oString Pointer Options(*String) Value; End-PR; Dcl-PR GetS Pointer ExtProc('gets'); Buffer Char(1024); End-PR; Dcl-Pr GetInput Char(1024); End-Pr; Dcl-S TempString VarChar(1024); PutS('Hello world. How are you?'); TempString = GetInput(); PutS('You wrote: ' + TempString); *InLr = *On; Return; Dcl-Proc GetInput; Dcl-PI GetInput Char(1024); End-PI; // Local work fields. Dcl-S InputString Char(1024); Dcl-S pInputString Pointer Inz(%Addr(InputString)); Dcl-S OutputString VarChar(1024); If GetS(InputString) = *Null; // An error occurred PutS('Something went wrong when getting input.'); Else; // Get all characters up to, not including the x'00' char. OutputString = %Str(pInputString); EndIf; Return OutputString; End-Proc;
Agreed, that using ‘puts’ and ‘gets’ requires more lines of code than DISPL does. However, if you put the declarations and the ‘GetInput’ procedure in your toolbox, they will be one-liners in your program code 😉