Is there anyway to redirect the input file into our program in OCaml?
Something like this:
filename.ml < input.<can be any extension>
I have googled for this problem. The module Unix comes up to mind but I really don't understand how it works.
Could someone please give me some suggestion? If I'm right about the Unix module, can you please give me an example of how it works?!
Thank you very much!
Since you know how to redirect from the command line, I assume you're asking how to redirect inside your program.
The first thing to figure out (if you'll excuse my saying so) is why you would want to do this. Anything that can be done through redirection can be done by opening a file for input and passing around the input channel. The only purpose of redirection is to hook the standard input channel up to a chosen file. But since you're writing the code you can read input from any channel you like.
One reason to do it is that it's a quick hack for testing. I've done this many times. Another possible reason is that you're using code you can't easily or (don't want to) modify.
If you really do want to redirect stdin, and you're running on a Unix-like system, you can handle redirection the way the shell actually handles it: with the dup2() system call.
$ cat redir.ml
let redir fn =
let open Unix in
let fd = openfile fn [O_RDONLY] 0 in
dup2 fd stdin
let () =
redir "redir.ml";
Printf.printf "%s\n" (read_line())
$ ocamlc -o redir unix.cma redir.ml
$ ./redir
let redir fn =
Related
I’m looking for a C/C++ way to execute a shell command and store the output of that command in a std::string or file, without the output being automatically printed to the console.
All approaches I’ve seen can do exactly that, but also print the execution result to the console.
For example with a combination of
FILE* pipe = popen("ls", "r");
and
fgets()
I’m able to do just that, but with the printing to the console.
Is there perhaps a way to redirect the stream’s buffer from std::cout to std::sstream, or has it semething to do with Ubuntu?
Any help is appreciated :)
The 2>&1 part from the comments did it.
What I'd like to do is have my C++ code open up Mplus (statistical program that I've downloaded on my computer) and run it. Is it possible?
You may be able to do what you want with std::system() calls like:
std::system("program -e input_commands.txt"); // Assuming it accepts some sort of command line args
std::system("program < input_commands.txt"); // Assuming it responds to stdin
It depends on the program if this approach will work.
I have a quick question, should be relatively simple for those who have some more experience in WMI-command processor than I do (and since I'm an absolute beginner thats not hard :-) )
I fail to understand why wmic /format switch works the way it does. I open up cmd.exe and type
wmic process list brief /format:htable > processlist.html
this does exactly what I want and no bothers further on. Whereas if I go to wmic processor, and try to execute the same command exactly as above...
wmic:root\cli>process list brief /format:htable > processlist.html
I receive the error tag: "Invalid XSL format (or) file name."
Here goes the screenshot. Note I have already copied XSL files from wbem to sys32 dir
Can someone explain to me why these 2 commands that for me look exactly the same, with the only difference that one is executed outside wmic environment and the other one is from inside, the latter one doesn't work? I just fail to understand it.
Please advise so I can comprehend this a bit better! :-)
Try this
copy /y %WINDIR%\system32\wbem\en-US\*.xsl %WINDIR%\system32\
And then
wmic:root\cli>process list brief /format:htable.xsl > processlist.html
Note the presence of the extension after "htable"
You are attempting to use CMD.EXE > redirection while you are within the interactive WMIC context. That can't work.
You can use the WMIC /output:filename switch while in interactive mode. Each subsequent command will overwrite the output of the previous command. You can get multiple commands to go to the same file by using /append:filename instead. You can reset the output back to stdout using /output:stdout.
/output:processlist.html
process list brief /format:htable
/output:stdout
Did you try specifying a full path in the wmic:root\cli>process call? My bets are that the first worked because it output the file to the current directory.
I have a simple C++ program that takes in inputs and outputs some string. Like this:
$ ./game
$ what kind of game? type r for regular, s for special.
$ r
$ choose a number from 1 - 10
$ 1
$ no try again
$ 2
$ no try again
$ 5
$ yes you WIN!
Now I want to write a c++ program can runs this c++ program and plays the game automatically without user input and then outputs it to a file or standard output.
Running it would look like this:
./program game r > outputfile
game is the game program, r for playing regular style.
How should I do this? The main reason I need this program is that I want to do automatic testing for a much bigger program.
You could use std::system from <cstdlib>:
std::system("game r > outputfile");
The return value is ./program's, the sole argument must be of type char const *.
There is no standard way to run a program and feed it standard input, though. Judging by your command line, you're on some Unix variant where popen from <stdio.h> should work:
FILE *sub = popen("game r > outputfile", "w");
then write to sub with the stdio functions and read outputfile afterwards.
(But for simple testing, I'd recommend implementing the core logic of your program as a set of functions/classes that can be run by a custom main function in a loop; or pick your favorite scripting language to handle this kind of thing.)
I'd be more efficient to add a caller function to your main source and have it control looping, logging, and feeding input. It would also not require system calls or other magic to pull off. Being a game programmer, we have our games play themselves as much as possible to help with debugging, and almost always this is done via internal code, not through external scripting or system calls. It makes it easier to feed viable input as well.
This scenario cries out for a "script", IMHO.
Bash, Perl, Python - you name it.
SIMPLEST CASE:
Just write a bash script to call ./program game r > outputfile.
Or ./program game r < test_input.txt > test_output.txt
For more advanced scenarios, you might want to look at "expect".
You might also want to look at "STAF", which might be a great way to "automate your automated tests":
http://staf.sourceforge.net/current/STAFFAQ.htm
My program needs to accept three kinds of input commands below:
./Myprogram input.txt
./Myprogram < input.txt
./Myprogram
I'm thinking about using argc to check the number of arguments to resolve the first two situations (since redirection doesn't count as an argument). But then I stuck on the last case, which simply waits for an user input.
I'm wondering if there is a way to tell if a redirection is present in the shell command?
For a more complicated scenario such as a mix of redirection and argv forms (see below). Is there a way to do it or it's simply a bad design for taking user commands?
./Myprogram input1.txt input2.txt input3.txt
./Myprogram input1.txt < input2.txt input3.txt
./Myprogram
Any help will be much appreciated!
Z.Zen
Redirection will never be seen by your program as an argument. So in:
./Myprogram input.txt
./Myprogram < input.txt
./Myprogram
the second and third forms are identical. As for your second set of possibilities:
./Myprogram input1.txt input2.txt input3.txt
./Myprogram input1.txt < input2.txt input3.txt
./Myprogram
the second line is equivalent to:
./Myprogram input1.txt input3.txt < input2.txt
and it's also indistinguishable from:
./Myprogram input1.txt input3.txt
(the only different being where standard input actually comes from).
A typical way some programs handle mixed input from stdin and files specified on the command line is to accept "-" as a special filename meaning "use stdin as the input file at this position in the argument list". Many such programs will default to processing a singleton-list of "-" if the argument list is empty.
The basic algorithm is:
if (there are no arguments left after parsing options)
call_function(stdin);
else
{
foreach remaining argument
{
FILE *fp;
if (strcmp(argument, "-") == 0)
call_function(stdin);
else if ((fp = fopen(argument, "r")) == 0)
...error handling...
else
{
call_function(fp);
fclose(fp);
}
}
}
You could pass the file name to the 'call_function()' too, and sometimes I write the code with the output file stream specified. That function ('call_function()') is what processes one file - reading to the end of the file. It does not close the file; it was given an open file and should not close it.
The first 'if' deals with the I/O redirection case, of course.
I wrote, many years go, a function to handle this loop. It simplifies my life whenever I need to write a command in this 'UNIX filter' idiom - which is quite often. Along with a standardized error reporting package, it greatly simplifies life. Having it as a function also permits me to use variants on it, such as one that creates a backup of the file before it is overwritten, or which safely overwrites the file if the function completes successfully.
#R.. is correct for the usual cases.
If you want to have interactive behavior in case #3 but not #2, beyond letting the terminal buffer the user's input by line, you can use isatty (specifically isatty(0)) to determine whether there's a person on the other end.
This is not standard C, but neither is the notion of a terminal or a shell!
I'm wondering if there is a way to tell if a redirection is present in the shell command?
No. From your program's point of view there is no difference between these two cases:
./Myprogram < input.txt
./Myprogram
In both the cases the program is not taking any command line argument and would get it's input from the standard input.In the first case it's the shell that is connecting the contents of the file input.txt to the stdin of your program your program knows nothing about this.
It is possible to tell whether there is data to read by using select() on stdin. This will not tell you whether there is a redirection (you won't be able to tell when the file is empty, or when for some reason the user managed to put something on stdin before your program got a chance to test for it). Whether it works for your case or not depends on what you want to do in borderline cases.
Alternatively, you can use isatty() on stdin to find out if it's a tty or not. It's what most programs will do to find out whether they are interactive or not, and probably better in your case.
Now, you may notice that blocking waiting for user input in the third case is what all standard tools do, and is probably the behavior most users expect of your program too.