2

I need to wrap a program in python and feed it input and print output. But if it give it one line of input it seems to use this as input until the program terminates. I've written a very basic program in C (called inout) which takes in two lines of input and prints out to stdout.

from subprocess import Popen, PIPE, STDOUT

p = Popen(['inout'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)
out, err = p.communicate(input=b'Why is this twice')

print(out)
print("done")

The output from this program is:

b'Why is this twice\r\nWhy is this twice\r\n'
done

How can I stop this from happening?

2
  • What does the source for inout look like? Commented May 23, 2015 at 17:10
  • @dano its actually c++ string in; getline(cin, in); cout << in << endl; getline(cin, in); cout << in << endl; Commented May 23, 2015 at 17:11

1 Answer 1

2

The bug is actually in your C++ program; it re-uses the in variable for both of its prints, which means if the second call to getline doesn't return anything (and it doesn't in your case, because the EOF of stdin is reached after the first getline call), the contents returned by the first getline call will be printed twice, because they're still saved inside in. This is obvious if you tweak your C++ program slightly to reset in between the two calls to getline:

#include <iostream>
using namespace std;

int main()
{
 string in; 
 getline(cin, in); 
 cout << in << endl; 
 in = ""; // reset in
 getline(cin, in); 
 cout << in << endl;
 return 0;
}

Output:

b'Why is this twice'


done

Edit:

Based on the requirements you gave in the comments, you want something like this:

from subprocess import Popen, PIPE, STDOUT

p = Popen(['./inout'], stdout=PIPE, stdin=PIPE, stderr=STDOUT, bufsize=0)  # bufsize=0 keeps stdout from being buffered.

# Send first line to inout
p.stdin.write(b'Why is this twice\n') 

# Read first line out output
first = p.stdout.readline()
print("got {}".format(first))

# Get line from user
a = input()

# Send second line to inout
p.stdin.write('{}\n'.format(a).encode('utf-8')) 

# Read second line from inout
second = p.stdout.readline()
print('also got {}'.format(second))

p.wait()
print("done")

Output:

got b'Why is this twice\n'
sdf  # This was typed by me
b'sdf\n'
done
Sign up to request clarification or add additional context in comments.

4 Comments

Okei, that actually fixed it. The original program did what it was ment to when run in windows for some reason. Anyway i now have a new problem which is that the program terminates without receiving the next line of input, it just assumes that its an empty line and completes. Any tips for that?
@Jens You need to actually send two lines to the stdin via p.communicate. Or, if you actually want one of the cin calls to be interactive, you need to not use p.communicate(input=...), and instead feed the first line to p.stdin directly (using p.stdin.write(b'Why is this twice?')), have the Python script ask for the second line on its own stdin, and then feed the inputted line to the child process. Then you can call p.communicate() to wait for the child to finish and get its stdout.
I actually need to receive the output of the child program after the first line, before giving it the second. Do you have any input on how to do this? Thanks for all the help so far by the way!
awsome, thanks! Wish i had the rep to upvote you! :)

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.