7

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.

3
  • Have you looked at pipes and how they work? Commented Jan 20, 2014 at 10:22
  • 1
    dup2 will likely get you where you want to go. Good luck. Commented Jan 20, 2014 at 10:23
  • You can do everything you could do from the command line using std::system, including redirecting input and output. Commented Jan 20, 2014 at 10:24

7 Answers 7

4

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;
}
Sign up to request clarification or add additional context in comments.

Comments

4

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.

7 Comments

You probably meant "In Linux, the key components are".
@Lundin, you probably meant "In POSIX environments, ..." ;)
@Shahbaz Since nobody but the *nix people seem to care about POSIX, that's essentially the same thing.
@Lundin, I don't mean to argue. Just letting you know that *nix is not just Linux. Anyway, I just said it for fun, forget about it.
@Shahbaz GNU's Not Unix? :)
|
3

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 :)

Comments

0

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

Comments

0

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.

Comments

0

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

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.