Get permanently the output from a shell command running in C++ - c++

I want to get the output from a shell command (my_program). Here is a example taken from this site:
#include <iostream>
#include <stdio.h>
using namespace std;
int main() {
FILE *in;
char buff[512];
if(!(in = popen("my_program", "r"))){
return 1;
}
while(fgets(buff, sizeof(buff), in)!=NULL){
cout << buff;
}
pclose(in);
return 0;
}
The problem:
I want to run my program permanently and get the output while the program is still running, NOT only get the output from the program once.
Any idea?

Your question is somewhat unclear but I suspect that the problem is buffer and the answer flushing: The way I understand is the program my_program produced outputs occassionally and the program you show should kick into action when my_program prints something. Further I suspect that this program doesn't produce a lot of output in total, e.g. less than 4k.
The problem is that most implementations buffer standard output differently depending of whether this is directed to a "console" or something else: when writing to the console output tends to be line-buffer while other destinations buffer substantially bigger buffers. However, the buffer can be explicitly flushed, reducing the performance of the output substantially. Of course, in the scenario above you'd be more interest in timely outputs rather than output performance.
A simple approach to flush an output buffer in C++ us to use out << std::flush. If you quickly want to verify that this the problem you can set up the stream to flush after every output operation using out << std::unitbuf. There are a number of other approaches to automatically flush but these are a bit more involved.

Related

Can I give auto input in VSCode and not have to type input every time

Generally we need to type the input after running any file where we have std::cin, like the C++ code in below
#include <iostream>
using namespace std;
int main()
{
// your code goes here
int t;
cin >> t;
}
I just don't like to enter the same input every time. So I want to automate this process for the same input, say I save my input in a file called input.txt and after running the file, it should take the input from input.txt and output the results. Of course saving input to the clipboard is one way but I might want to copy other things while coding and copy-pasting is itself is again one small job.
I use VS code editor in windows and run code in terminal extension.
The solution is to learn to use your shell. I’m assuming a Unix-like shell here.
Type all of your inputs into a file as you would enter them while the program is running. Save it.
When you run your program, use the command a.out < input.txt. Substitute the appropriate names, obviously.
Your program will read the inputs from the file as if they had been typed in.
Note that because nothing was actually typed in, your formatting might look a bit off, but it’s not a big deal compared to the time you’re saving in running your tests.
You could use, following function inside your main function
int main() {
freopen('input.txt', 'r', stdin);
freopen('output.txt', 'w', stdout); //if you want to save output to a file.
/*
... your code
*/
}

c++ stream buffer and flush

#include <iostream>
#include <chrono>
#include <thread>
using namespace std::chrono;
int main() {
std::cout << "hello";
std::this_thread::sleep_for(2s);
std::cout << "world"<<std::endl;
}
I m using visual studio 2019.
I expect above code to print helloworld after 2 seconds but hello is displayed before 2 seconds in the console(i.e instantly when i run the program) and world is displayed after 2 seconds.
I read about buffer recently and came to know that the text should be displayed in the console only after the buffer is full.
We can force to flush the buffer by using \n, manupulators and cin.
But why am I not seeing desired behavior in this particular example?
Isn't cout using buffer?
Is it flushed for every character?
There is no strict rule in the standard when a buffer should be flushed.
Like #Yksisarvinen mentioned in the comments, a flush isn't affected by the compiler but by the operating system. Also \n doesn't always trigger a flush. If the cout is going to a terminal, it is usually line buffered, thus you can force a flush via \n.
More information can be found at:
When does cout flush?
and
Does new line character also flush the buffer?

WriteFile function with assembly debugging (syncing)

First of all, this question is based on my last question here: Reading Console Buffer / Output C++
I have a compiled executable binary file. It has some outputs, what I would like to redirect it to an other program, that handles the lines. I successfully found where the output is sent, and I modified it to STDOUT. The problem is that, when I use it like:
./jampDed.exe | stdout.exe
then the output is not synced. I got the content after every 1000-2000 bytes.
stdout.cpp
#include <iostream>
int main() {
std::string s;
while (std::getline(std::cin, s, '\n')) {
std::cout << s << std::endl;
}
return 0;
}
I also created a picture about assembly modification, where Kernel32.WriteFile function was used by default.
So the question is that, how can I make it synced? How to get every line as soon as it happens on the dedicated server?
Somewhere in the executable where it establishes stdout is an option bit for unbuffered output. Just set (or clear) that bit. Then every call to write is transferred without delay. This adds significant execution time and i/o system effort to that program but is probably okay for this.
The program which processes that output (as input) should buffer full lines because the program is unlikely to do full line output itself.
Why don't you try:
std::cout << s << std::endl << std::flush;
^^^^^^^^^^

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.

Redirect both cout and stdout to a string in C++ for Unit Testing

I'm working on getting some legacy code under unit tests and sometimes the only way to sense an existing program behavior is from the console output.
I see lots of examples online for how to redirect stdout to another file in C++, but is there a way I can redirect it to an in-memory stream so my tests don't have to rely on the disk?
I'd like to get anything that the legacy code sends to stdout into a std::string so I can easily .find on the output.
Edit
The legacy code is so bad that it users a mixture of cout << .. and printf. Here is what I have so far:
void TestSuite::setUp(void)
{
oldStdoutBuf = std::cout.rdbuf();
std::cout.rdbuf(consoleOutput.rdbuf());
}
void TestSuite::tearDown(void)
{
std::cout.rdbuf(oldStdoutBuf);
}
The problem is that this does not capture output using printf. I would like something that gets both. Any ideas?
std::stringstream may be what you're looking for.
UPDATE
Alright, this is a bit of hack, but maybe you could do this to grab the printf output:
char huge_string_buf[MASSIVE_SIZE];
freopen("NUL", "a", stdout);
setbuf(stdout, huge_string_buffer);
Note you should use "/dev/null" for linux instead of "NUL". That will rapidly start to fill up huge_string_buffer. If you want to be able to continue redirecting output after the buffer is full you'll have to call fflush(), otherwise it will throw an error. See std::setbuf for more info.
You can use freopen(..., stdout) and then dump the file into memory or a std::string.
This may be an alternative:
char bigOutBuf[8192];
char savBuf[8192];
fflush(stdout);
setvbuf(stdout,bigOutBuf,IOFBF,8192);//stdout uses your buffer
//after each operation
strncpy(savBuf,bigOutBuf,8192);//won't flush until full or fflush called
//...
//at long last finished
setbuf(stdout,NULL);//reset to unnamed buffer
This just intercepts the buffered output, so still goes to console or wherever.
Hope this helps.
Try sprintf, that's more efficient.
int i;
char str[] = "asdf";
char output[256];
sprintf(output, "asdfasdf %s %d\n", str, i);