Piping input to an already running cpp program? - c++

include
Lets assume that this is the code I am running:
int main(int argc, char **argv) {
bool running = true;
string lineInput;
while (running)
{
while (cin >> lineInput)
{
cout << lineInput;
}
}
return 0;
}
What I would like to have happen is that I can call start a program from terminal by typing "./myProgram" That part is fairly straight forward. The part I'm not sure how to do is make it so that I can at a later point in time type echo "some text to echo" | myProgram and be able to have my program then print that text back out to the terminal.
Right now I can only make it work if I type:
echo "blah blah blah" | ./myProgram
So my goal is to have two separate steps. One where I start my program, and a second when I pipe it some input to use

I'm thinking you could do this with a named pipe.
mkfifo mypipe
./myProgram < mypipe &
cat file1.txt file2.txt file3.txt > mypipe

You can use mkfifo, and just read from that in the program as from an ordinary file.
There's also
pipe or socket_pair (bi-directional)

Related

Reading input using command in c++

I am trying to read a string into my program from the terminal. So the command I want to use is eg g++ -g -std=c++11 main.cpp -o out to compile, then ./out < file.txt to run my program. But I, however, get an error when I use a < symbol when running my program.
int main(int argc, char** argv){
cout << "Checking this " << argv[1] << endl;
return 0;
}
I want my program to output Checking this file.txt but I want to run it this way, ./out < file.txt NOT THIS AWAY ./out file.txt
This is not possible with this configuration. You would have to run the program as ./out file.txt and then have the program read in from file.txt which will have the file name stored in argv[1] assuming this order.
POSIX compliant shells when you run ./out < file.txt will just give your program the contents of file.txt in stdin. The < file.txt part is not visible to your program.

passing input value from bash script to a c++ executable

I have a c++ code which requires an input value. I would like to have a bash script to run my c++ executable file automatically. My bash script is below:
#!/bin/bash
g++ freshness.cpp -g -o prob
for((i=0;i<30;i++))
{
./prob<$2 ../../data/new_r.txt ../../data/new_p.txt ../../data /t_$1.txt >> result.txt
}
./cal result.txt
rm result.txt
My main.cpp is below:
int main(int argc,char*argv[])
{
map<int, struct Router> nodes;
cout<<"creating routers..."<<endl;
Create_router(argv[1],nodes);
cout<<"creating topology..."<<endl;
LoadRouting(argv[2],nodes);
cout<<"simulating..."<<endl;
Simulate(argv[3],nodes);
return 0;
}
There is a cin in Create_router(argv[1],nodes), like cin>>r_size;
Many thanks in advance.
./prob < $2
means to redirect the input of the program to a file whose name is in the $2 variable.
If $2 is the actual input data, not a filename, then you should use a here-string:
./prob <<< "$2" ../../data/new_r.txt ../../data/new_p.txt ../../data /t_$1.txt >> result.txt
or a here-doc:
./prob <EOF ../../data/new_r.txt ../../data/new_p.txt ../../data /t_$1.txt >> result.txt
$2
EOF
or pipe the input to the program:
printf "%s\n" "$2" | ./prob ../../data/new_r.txt ../../data/new_p.txt ../../data /t_$1.txt >> result.txt
The here-string method is the simplest, but it's a bash extension. The other methods are portable to all POSIX shells.

how to turn program into deamon program

I sometimes write program like this to process offline data:
load_model() //this may cost lots of time
while(cin >> inputs)
{
result = process_input(inputs)
cout << result
}
release_model()
This works fine if I only have to process offline data. However, when the data comes one by one I am in trouble. Since I have to load the model everytime which is time consuming.
I wonder if there is any way to CONVERT this program into a service WITHOUT modify the program itself. For example, I can redirect the cin and cout to two named pipes:
program < namedpipe_in > namedpipe_out
The I can put the inputs into the namedpipe_in like this
cat input > namedpipe_in
and read the result in another pipe:
cat namedpipe_out
However, this solution will not work since once I cat something to the namedpipe_in, the pipe will be close after cat operation and the program exits.
My question is how to fix this problem and make the pipes looks more like a queue instead of a memory buffer.
Thanks for your time reading.
Perhaps I am misunderstanding your question; please correct me if this is not what you are looking for.
To simulate your example, I wrote a simple C++ program which just takes in each input string and reverses it:
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
std::cout << ":start:" << std::endl;
std::string str;
while(std::cin >> str)
{
std::reverse(str.begin(), str.end());
std::cout << str << std::endl;
}
}
The output binary of my example program is strflipper.
I have another file called in.log which is just an input file which I created via touch in.log.
Now I call
tail -f in.log | ./strflipper > out.log
and if I add something to the input log in a different terminal, the output log gets adjusted as such:
$ echo "abc" >> in.log
$ echo "foo" >> in.log
$ echo "bar baz" >> in.log
$ cat out.log
:start:
cba
oof
rab
zab
which of course is my expected output. As long as I don't kill the program, anything I add into in.log will automatically be processed within that loop without killing or restarting strflipper.

How do I execute a string as a shell script in C++?

I'm writing a program that needs to be able to execute a shell script provided by the user. I've gotten it to execute a single shell command, but the scripts provided will be more complicated than that.
Googling got me as far as the following code snippet:
FILE *pipe;
char str[100];
// The python line here is just an example, this is *not* about executing
// this particular line.
pipe = popen("python -c \"print 5 * 6\" 2>&1", "r");
fgets(str, 100, pipe);
cout << "Output: " << str << endl;
pclose(pipe)
So that this point str has 30 in it. So far so good. But what if the command has carriage returns in it, as a shell script file would, something like the following:
pipe = popen("python -c \"print 5 * 6\"\nbc <<< 5 + 6 2>&1", "r");
With this my goal is that str eventually have 30\n11.
To put another way, assume I have a file with the following contents:
python -c "print 5 * 6"
bc <<< 5 + 6
The argument I'm sending to popen above is the string representation of that file. I want to, from within C++, send that string (or something similar) to bash and have it execute exactly as if I were in the shell and sourced it with . file.sh, but setting the str variable to what I would see in the shell if it were executed there, in this case, 30\n11.
Yes, I could write this to a file and work it that way, but that seems like it should be unnecessary.
I wouldn't think this was a new problem, so either I'm thinking about it in a completely wrong way or there's a library that I simply don't know about that already does this.
use bash -c.
#include <stdio.h>
int main()
{
FILE *pipe = popen("bash -c \"echo asdf\necho 1234\" ", "r");
char ch;
while ((ch = fgetc(pipe)) != EOF)
putchar(ch);
}
Output:
asdf
1234
(I've test on cygwin)

devc++ input from file does not work

I'm trying to redirect a .txt content to .exe
program.exe < file.txt
and contents of file.txt are
35345345345
34543534562
23435635432
35683045342
69849593458
95238942394
28934928341
but the first index in array is the file path and the file contents is not displayed.
int main(int argc, char *args[])
{
for(int c = 0; c<argc; c++){
cout << "Param " << c << ": " << args[c] << "\n";
}
system("PAUSE");
return EXIT_SUCCESS;
}
Desired output:
Param0: 35345345345
Param1: 34543534562
Param2: 23435635432
Param3: 35683045342
Param4: 69849593458
Param5: 95238942394
Param6: 28934928341
The myapp < file.txt syntax passes to stdin (or cin if you prefer), not the arguments.
You have misunderstood what argc and argv are for. They contain the command line arguments to your program. If, for example, you ran:
program.exe something 123
The null terminated strings pointed to by argv will be program.exe, something, and 123.
You are attempting to redirect the contents of a file to program.exe using < file.txt. This is not a command line argument. It simply redirects the contents of the file to the standard input of your program. To get those contents you will need to extract from std::cin.
When you say "but the first index in array is the file path and the file contents is not displayed." it sounds like you're trying to read input from argv and argc. The angle bracket shell operator does not work that way. Instead, stdin (what cin and several C functions read from) has the contents of that file. So, to read from the file in the case above, you'd use cin.
If you instead really wanted to have a file automatically inserted into the argument list, I can't help you with the windows shell. However, if you have the option of using bash, the following will work:
program.exe `cat file.txt`
The backtick operator expands into the result of the command contained within, and so the contents are then passed as arguments to program.exe (again, under the bash shell and not the windows shell)
This code does what i was expecting to do with the other one. Thanks everybody who helped.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string line;
while (getline(cin, line))
cout << "line: " << line << '\n';
}