I have a simple c++ program that I'm trying to execute through a python script. (I'm very new to writing scripts) and I'm having trouble reading output through the pipe. From what I've seen, it seems like readline() won't work without EOF, but I want to be able to read in the middle of the program and have the script respond to whats being outputted. Instead of reading output, it just hangs the python script:
#!/usr/bin/env python
import subprocess
def callRandomNumber():
print "Running the random guesser"
rng=subprocess.Popen("./randomNumber", stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
i=50
rng.stdin.write("%d\n" % i)
output=rng.stdout.readline()
output=rng.stdout.readline()
callRandomNumber()
and the c++ file, which generates a random number between one and 100, then checks the users guess until they guess correctly
#include<iostream>
#include<cstdlib>
using namespace std;
int main(){
cout<<"This program generates a random number from 1 to 100 and asks the user to enter guesses until they succuessfully guess the number. It then tells the user how many guesses it took them"<<endl;
srand(time(NULL));
int num=rand()%100;
int guessCount=0;
int guess=-1;
cout<<"Please enter a number: ";
cin>>guess;
while(guess!=num){
if(guess>num){cout<<"That guess is too high. Please guess again: ";}
else{cout<<"That guess is too low. Please guess again: ";}
cin>>guess;
guessCount++;
}
cout<<"Congratulations! You solved it in "<<guessCount<<" guesses!"<<endl;
return 0;
}
the eventual goal is to have the script solve the problem with a binary search, but for now I just want to be able to read a line without it being the end of the file
As @Ron Reiter pointed out, you can't use
readline()
becausecout
doesn't print newlines implicitly -- you either needstd::endl
or"\n"
here.For an interactive use, when you can't change the child program,
pexpect
module provides several convenience methods (and in general it solves for free: input/output directly from/to terminal (outside of stdin/stdout) and block-buffering issues):It works but it is a binary search therefore (traditionally) there could be bugs.
Here's a similar code that uses
subprocess
module for comparison:You may have to explicitly close
stdin
, so the child process will stop hanging, which I think is what is happening with your code -- this can be verified by running top on a terminal and checking ifrandomnumber
's status stays sleeping and if it is using 0% CPU after the expected time it would take to execute.In short, if you add
rng.stdin.close()
right after therng=subprocess(...)
call, it may resume with no problem. Another option would be to dooutput=rng.communicate(stdin="%d\n" % i)
and look atoutput[0]
andoutput[1]
who arestdout
andstderr
, respectively. You can find info oncommunicate
here.I'm pretty sure adding newlines in your C++ program will cause the readlines to return.