Question
I want it to 'listen' to the standard input stream in a running (compiled) Matlab executable.
This is how I believe it is done in c
or a similar language:
#include stdio.h
fgets(line, 256, stdin)
Or more elaborately, it it can be used as such:
if (!fgets(line, 256, stdin))
return;
if (line[0] == '\n')
continue;
sscanf(line, "%s", command);
Answer
For completeness I will leave the background and notes intact, but with the help of Amro and EitanT I have managed to work it out.
Background
I have found how to do this in other languages, and here are some instructions for the compilation process.
However, I have not found anywhere how to 'listen' to the input in Matlab. The closest I have come is this description of C-like IO in Octave, but I cannot make progress with this as I looking for a solution in MATLAB.
Note that altering or wrapping the program that sends the data over the stream is not possible, and that I would prefer a pure MATLAB solution rather than wrapping my entire program. If I were to call a trivial function from MATLAB in a different language that would be ok.
What have I tried?
I tried a few functions from the command window like fgets(0)
(fid = 0
seems to be the id corresponding to stdin
(as mentioned by @EitanT and seen when trying fopen(0)
) )but it just returns:
Operation is not implemented for requested file identifier.
I have also considered using the option in MATLAB to invoke system commands or execute java
/ perl
commands, but so far without luck. I am also not sure whether these would still work after compilation.
Furthermore I attempted to use input('prompt','s')
this works when I open the program via cmd
, but does not do anything until I hit enter. (Which the program that I listen to of course will never do, in the best case I can get \n
at the end of each line).
I also tried out waitinput
from File Exchange but I think this is a dead end as it did not catch anything and seems to perform quite poorly.
Notes
popen
on File Exchange but that does not seem to be available for Windows.'show me'
this is properly sent to the standard output stream.It turns out that input
reads the standard input stream.
The reason why I failed to collect my inputs, is because I was using it as follows:
input('prompt','s')
As a result the string 'prompt'
was sent to the program calling my application, and as it considered this an invalid response/request it did not send anything.
I have succeeded in making a small test program, and unlike I suspected before it is NOT a problem that the other application doesn't hit enter after sending a command.
The general solution
This is the way I have my current setup,
while 1
stdin = input('','s'); % Note the empty first argument
if ~isempty(stdin)
stdout = process_input(stdin);
stdout % Displaying the result (And thus sending it to stdout)
end
end
Let me illustrate with a toy example. Consider the following MATLAB function:
function greet()
str = input('Enter your name: ','s');
fprintf('Hello %s\n',str)
end
Now lets compile it into a standalone application. Note that if you use the deploytool
tool, make sure to choose "Console application" NOT "Windows standalone application" as target. The latter apparently produces an executable where the standard input is connected to the system shell not the MATLAB command prompt..
If you prefer to directly compile it yourself, use the following invocation:
mcc -o hello -W main:hello -T link:exe -N -v greet.m
(For reference, the "Windows app" target issues -W WinMain:hello
instead)
Running the executable produces:
C:\> hello
Enter your name: Amro
Hello Amro
where the input from the keyboard is correctly handled.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With