Question

Say I have an .exe, lets say sum.exe. Now say the code for sum.exe is

void main ()
{
 int a,b;
 scanf ("%d%d", &a, &b);
 printf ("%d", a+b);
}

I wanted to know how I could run this program from another c/c++ program and pass input via stdin like they do in online compiler sites like ideone where I type the code in and provide the stdin data in a textbox and that data is accepted by the program using scanf or cin. Also, I wanted to know if there was any way to read the output of this program from the original program that started it.

Was it helpful?

Solution 4

How to do so is platform dependent.

Under windows, Use CreatePipe and CreateProcess. You can find example from MSDN : http://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx

Under Linux/Unix, you can use dup() / dup2()

One simple way to do so is to use a Terminal (like command prompt in windows) and use | to redirect input/output.

Example:

program1 | program2

This will redirect program1's output to program2's input. To retrieve/input date, you can use temporary files, If you don't want to use temporary files, you will have to use pipe.

For Windows, (use command prompt):

program1 <input >output 

For Linux, you can use tee utility, you can find detail instruction by typing man tee in linux terminal

OTHER TIPS

In C on platforms whose name end with X (i.e. not Windows), the key components are:

  1. pipe - Returns a pair of file descriptors, so that what's written to one can be read from the other.

  2. fork - Forks the process to two, both keep running the same code.

  3. dup2 - Renumbers file descriptors. With this, you can take one end of a pipe and turn it into stdin or stdout.

  4. exec - Stop running the current program, start running another, in the same process.

Combine them all, and you can get what you asked for.

The easiest way I know for doing this is by using the popen() function. It works in Windows and UNIX. On the other way, popen() only allows unidirectional communication.

For example, to pass information to sum.exe (although you won't be able to read back the result), you can do this:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *f;

    f = popen ("sum.exe", "w");
    if (!f)
    {
        perror ("popen");
        exit(1);
    }

    printf ("Sending 3 and 4 to sum.exe...\n");
    fprintf (f, "%d\n%d\n", 3, 4);

    pclose (f);
    return 0;
}

This is my solution and it worked:

sum.cpp

#include "stdio.h"
int main (){
  int a,b;
  scanf ("%d%d", &a, &b);
  printf ("%d", a+b);
  return 0;
}

test.cpp

#include <stdio.h>
#include <stdlib.h>

int main(){
  system("./sum.exe < data.txt");
  return 0;
}

data.txt

3 4

Try this solution :)

It sounds like you're coming from a Windows environment, so this might not be the answer you are looking for, but from the command line you can use the pipe redirection operator '|' to redirect the stdout of one program to the stdin of another. http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/redirection.mspx?mfr=true

You're probably better off working in a bash shell, which you can get on Windows with cygwin http://cygwin.com/

Also, your example looks like a mix of C++ and C, and the declaration of main isn't exactly an accepted standard for either.

How to do this (you have to check for errors ie. pipe()==-1, dup()!=0, etc, I'm not doing this in the following snippet).

This code runs your program "sum", writes "2 3" to it, and than reads sum's output. Next, it writes the output on the stdout.

#include <iostream>
#include <sys/wait.h>
#include <unistd.h>

int main() {

    int parent_to_child[2], child_to_parent[2];
    pipe(parent_to_child);
    pipe(child_to_parent);

    char name[] = "sum";
    char *args[] = {name, NULL};
    switch (fork()) {

    case 0:
        // replace stdin with reading from parent
        close(fileno(stdin));
        dup(parent_to_child[0]);
        close(parent_to_child[0]);

        // replace stdout with writing to parent
        close(fileno(stdout));
        dup(child_to_parent[1]);
        close(child_to_parent[1]);

        close(parent_to_child[1]); // dont write on this pipe
        close(child_to_parent[0]); // dont read from this pipe

        execvp("./sum", args);
        break;

    default:
        char msg[] = "2 3\n";

        close(parent_to_child[0]); // dont read from this pipe
        close(child_to_parent[1]); // dont write on this pipe

        write(parent_to_child[1], msg, sizeof(msg));
        close(parent_to_child[1]);

        char res[64];
        wait(0);
        read(child_to_parent[0], res, 64);
        printf("%s", res);
        exit(0);
    }
}

I'm doing what @ugoren suggested in their answer:

  • Create two pipes for communication between processes
  • Fork
  • Replace stdin, and stdout with pipes' ends using dup
  • Send the data through the pipe

Based on a few answers posted above and various tutorials/manuals, I just did this in Linux using pipe() and shell redirection. The strategy is to first create a pipe, call another program and redirect the output of the callee from stdout to one end of the pipe, and then read the other end of the pipe. As long as the callee writes to stdout there's no need to modify it.

In my application, I needed to read a math expression input from the user, call a standalone calculator and retrieve its answer. Here's my simplified solution to demonstrate the redirection:

#include <string>
#include <unistd.h>
#include <sstream> 
#include <iostream> 

// this function is used to wait on the pipe input and clear input buffer after each read    
std::string pipeRead(int fd) { 
    char data[100];
    ssize_t size = 0;
    while (size == 0) {
        size = read(fd, data, 100);
    }
    std::string ret = data;
    return ret;
}

int main() {
    // create pipe
    int calculatorPipe[2];
    if(pipe(calculatorPipe) < 0) {
        exit(1);
    }
    
    std::string answer = "";
    std::stringstream call;

    // redirect calculator's output from stdout to one end of the pipe and execute
    // e.g. ./myCalculator 1+1 >&8
    call << "./myCalculator 1+1 >&" << calculatorPipe[1];
    system(call.str().c_str());

    // now read the other end of the pipe
    answer = pipeRead(calculatorPipe[0]);
    std::cout << "pipe data " << answer << "\n";

    return 0;
}

Obviously there are other solutions out there but this is what I can think of without modifying the callee program. Things might be different in Windows though.

Some useful links:

https://www.geeksforgeeks.org/pipe-system-call/

https://www.gnu.org/software/bash/manual/html_node/Redirections.html

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top