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 😉
