How to send input to stdin from code not terminal? - c++

I want to send input to a variable without having to type it in the terminal, as i am implementing a test case. for example consider the input to be sent is 2:
int a;
cin >> a;
The code should not wait for the user to give input, it should enter 2 there and populate a by itself.
i cant use the cin buffer, also taking input is compulsory.

you could create unnamed pipes pipe pd[2] and dup stdin & stdout to the pipe fds.
then write "2" into one pipe and read it from another.

You can get your input from a stringstream instead:
std::stringstream data = "2";
int a;
data >> a;

The basic question here (at least in my mind) is whether you're trying to write a single program, so that one part of the program provides the input to another part of the program, or you're writing two separate programs, one of which provides input to the other.
#Madhu Narayanan has already given a good summary of how you'd go about writing the code for the first case.
But, by far the preferable way to handle things inside a program is to have something like a function that takes (a reference to) an iostream as a parameter, so you can pass std::cin to read from the console, or some stringstream to have it read some predetermined data instead.
If what you care about is the second case, then you'd probably want to use popen (or Microsoft calls it _popen), which will spawn a child process, and connect a pipe to either its standard input or its standard output (but, regrettably, not both). So if this is what you want you'd do something like this:
// spawn the child, getting a handle to its standard input:
FILE *child = popen("child program", "w");
// write the input to the child:
if (child != nullptr) {
fprintf(child, "%d", 2);
}
For better or worse, there's no analog of this that gives you access to the child via an iostream (at least, not a pre-written one in the standard library, anyway).

Related

Send Character TO CONIN$ (Windows Console)

If you want to spawn a Windows console in an otherwise SUBSYSTEM:WINDOWS application you can use this code:
if (AllocConsole())
{
FILE* file = nullptr;
_wfreopen_s(&file, L"CONIN$", L"r", stdin);
_wfreopen_s(&file, L"CONOUT$", L"w", stdout);
_wfreopen_s(&file, L"CONOUT$", L"w", stderr);
}
The _wfreopen_s function maps stdin to CONIN$ and provides a pointer to pointer in the file variable (which we are effectively discarding).
What I'd like to do is instead map an input from something other than stdin, for example, another file stream and then write that stream to CONIN$.
For a larger picture of what I'm trying to do here, I've got a secondary thread running std::getline(std::cin... which blocks. I'd like the thread context object to just send a \n to the console to break the blocking call.
If there are other ideas, I'm open. The alternative currently is that I print a message to the console that says "Shutting down, press ENTER to quit..." Which, I guess, also works ;)
What I tried was using the FILE* conin = new FILE(); and then did a memcpy to fill it with a \n and then I used WriteFile to that pointer, thinking that it might write the file stream out to CONIN$, and while the code compiles, and the contents of the FILE* appears to be correct (0x0a), it does not appear to send that stream to the console.
I tested this by having std::cout above and below the code testing the stream write. If it works, I'd expect the two lines to be on separate lines, but they always show up on the same, suggesting that I'm not sending the file stream.
Thanks for reading!
You should not discard the FILE* handle, otherwise you won't be able to manipulate it, in particular you won't be able to properly flush/close it if required.
If you're working with threads, simply give the FILE* to the thread that requires it. Threads share the same memory space.
If you're working with processes, then you should create a pipe between the two processes involved (see Win32 API for CreatePipe for details), and connect one's stdout to the other's stdin.

using c++ input stream cin without blocking

I am trying to use the c++ standard input stream cin to get a user input without blocking the execution of the program. I have this code:
char ch;
int flag=1;
do
{
if(cin.rdbuf()->in_avail())
{
cin.get(ch);
flag=0;
}
else
//do something else
}while(flag);
//do something with the input
The idea here is to wait for user input without blocking while doing something else and as soon as the user provides an input we process the input( all in one thread). I know from the documentation the streambuf class used by the input stream provides the in_avail() function which will return a non-zero values when ever there is input ready in the buffer. The code above is not working as i expected it and is looping forever even if i provide a keyboard input at some point. i am using MS visual studio 2005 in windows 7. what am i missing here?
The function in_avail does:
Returns the number of characters available in the get area.
The get area may be empty even if some characters are readable from the underlying operating system buffer.
You will trigger a refill of the get area when you effectively call a read operation on the streambuf. And that operation will block. The reason is that the method underflow which is responsible for filling the get area:
Ensures that at least one character is available in the input area
And to ensure this, it must block until some character is read.

Capturing child stdout to a buffer

I'm developing a cross platform project currently. On windows i had a class that ran a process/script (using a commandline), waited for it to end, and read everything from it's stdout/stderr to a buffer. I then printed the output to a custom 'console'. Note: This was not a redirection of child stdout to parent stdout, just a pipe from child stdout to parent.
I'm new to OSX/unix-like api's but i can understand the canonical way of doing something like this is forking and piping stdouts together. However, i dont want to redirect it to stdout and i would like to capture the output.. It should work pretty much like this (pseudocode, resemblance with unix functions purely coincidental):
class program
{
string name, cmdline;
string output;
program(char * name, char * cmdline)
: name(name), cmdline(cmdline) {};
int run()
{
// run program - spawn it as a new process
int pid = exec(name, cmdline);
// wait for it to finish
wait(pid);
char buf[size];
int n;
// read output of program's stdout
// keep appending data until there's nothing left to read
while (read(pid, buf, size, &n))
output.append(buf, n);
// return exit code of process
return getexitcode(pid);
}
const string & getOutput() { return output; }
};
How would i go about doing this on OSX?
E:
Okay so i studied the relevant api's and it seems that some kind of fork/exec combo is unavoidable. Problem at hand is that my process is very large and forking it really seems like a bad idea (i see that some unix implementations can't do it if the parent process takes up 50%+ of the system ram).
Can't i avoid this scheme in any way? I see that vfork() might be a possible contender, so maybe i could try to mimic the popen() function using vfork. But then again, most man pages state that vfork might very well just be fork()
You have a library call to do just that: popen. It will provide you with a return value of a file descriptor, and you can read that descriptor till eof. It's part of stdio, so you can do that on OSX, but other systems as well. Just remember to pclose() the descriptor.
#include <stdio.h>
FILE * popen(const char *command, const char *mode);
int pclose(FILE *stream);
if you want to keep output with absolutely no redirection, the only thing we can think of is using something like "tee" - a command which splits the output to a file but maintains its own stdout. It's fairly easy to implement that in code as well, but it might not be necessary in this case.

How to Determine if STDIN is Empty?

I'm writing an emulator for my Operating Systems course. The problem I have is that we need to get all our .job files (they are like application programs being fed to the emulator) from STDIN and read them in.
Call:
./RMMIX < aJob.job
I just slurp it with
while(getline(std::cin, line))
line by line. The problem is, if I do not put anything to STDIN, then cin will wait for user input- NOT what I want. I need the program to recognize a lack of text on STDIN and terminate, not wait for user input instead.
I have determined that I can query the length like so:
size_t beg = std::cin.tellg();
std::cin.seekg(0, std::ios_base::end);
size_t end = std::cin.tellg();
std::cin.seekg(0, std::ios_base::beg);
and terminate if std::cin has a length of 0.
Are there any other solutions to this? Is this a portable solution?
I don't think there's a platform independent way of doing this, but on Unix-based systems you should be able to do:
#include <unistd.h>
...
int main() {
if (!isatty(0)) {
// stdin is being streamed from a file or something else that's not a TTY.
}
...
}
However, I think doing it via a command line option is the preferred approach.
You need to redesign your program. Instead of reading from standard input, read from a named file, who's name you provide on the command line. Then instead of:
./RMMIX < aJob.job
you say:
./RMMIX aJob.job
This is much easier and more portable than trying to determine if there is anything in standard input.
You might also look at this http://www.programmersheaven.com/mb/CandCPP/232821/232821/non-blocking-reads-on-stdin/ for an idea that comes at the problem from another direction -- don't check the number of bytes on the stream, but instead just make the read succeed immediately and then check to see if anything was read.
You can press Ctrl+D on the command line to signal end-of-file for standard input on the running program.
This is desired behavior. Otherwise, if programs exited immediately when no input remained, pipelines could randomly be broken by commands that were waiting on another command that had not been scheduled to run (and that had not produced any additional output), or that buffered output and emitted it all at once, like sort does.
When using io redirection to pull stdin from a file via something like ./RMMIX < file.txt, this end-of-file condition is signaled automatically when there is no more data left in the file. For input read from a terminal, waiting is probably the desired behavior.

How to redirect data to stdin within a single executable?

I am using cxxtest as the test framework for my C++ classes, and would like to figure out a way to simulate sending data to classes which would normally expect to receive it from standard input. I have several different files which I would like to send to the classes during different tests, so redirection from the command line to the test suite executable is not an option.
Basically, what I would really like to do is find a way to redefine or redirect the 'stdin' handle to some other value that I create inside of my program, and then use fwrite() from these tests so that the corresponding fread() inside of the class pulls the data from within the program, not from the actual standard I/O handles associated with the executable.
Is this even possible? Bonus points for a platform-independent solution, but at a very minimum, I need this to work with Visual Studio 9 under Windows.
The appropriate method is to rewrite your classes so that they are testable. They should accept as a parameter the handle, stream or file from which they are supposed to read data - in your test framework, you can then mock in the stream or supply the path to the file containing the test data.
You should be able to use freopen() to point stdin to an arbitrary file.
rdbuf does exactly what you want. You can open a file for reading and replace cin's rdbuf with the one from the file. (see the link for a example using cout).
On unix-like OS you could close the 0 file handle (stdin) and open another file. It will have the lowest avaiable handle, which in this case would be 0. Or use one of posix calls that do exactly this. I'm not sure, but this may also work on Windows.
I think you want your classes to use an input stream instead of std::cin directly. You'll want to either pass the input stream into the classes or set it on them via some method. You could, for exmaple, use a stringstream to pass in your test input:
std::istringstream iss("1.0 2 3.1415");
some_class.parse_nums(iss, one, two, pi);
We can redirect cin in order it read data from a file. Here is an example :
#include <iostream>
#include <fstream>
#include <string>
int main()
{
std::ifstream inputFile("Main.cpp");
std::streambuf *inbuf = std::cin.rdbuf(inputFile.rdbuf());
string str;
// print the content of the file without 'space' characters
while(std::cin >> str)
{
std::cout << str;
}
// restore the initial buffer
std::cin.rdbuf(inbuf);
}