Ich habe ein einfaches C++-Programm, das ich über ein Python-Skript auszuführen versuche. (Ich bin sehr neu im Schreiben von Skripten) und ich habe Probleme beim Lesen der Ausgabe durch die Pipe. Nach dem, was ich gesehen habe, scheint es, als würde readline() ohne EOF nicht funktionieren, aber ich möchte in der Lage sein, mitten im Programm zu lesen und das Skript auf die Ausgabe reagieren zu lassen. Anstatt die Ausgabe zu lesen, hängt es einfach das Python-Skript auf:
und die c++-Datei, die eine Zufallszahl zwischen eins und 100 generiert, überprüft dann die Vermutung des Benutzers, bis er richtig geraten hat
#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;
}
Das letztendliche Ziel ist, dass das Skript das Problem mit einer binären Suche löst, aber im Moment möchte ich nur eine Zeile lesen können, ohne dass dies das Ende der Datei ist
jfs
Wie @Ron Reiter betonte, können Sie nicht verwenden readline() weil cout druckt nicht implizit Zeilenumbrüche – Sie müssen es auch std::endl oder "n" Hier.
Hier ist ein ähnlicher Code, der verwendet subprocess Modul zum Vergleich:
#!/usr/bin/env python
from __future__ import print_function
import sys
from subprocess import Popen, PIPE
p = Popen("./randomNumber", stdin=PIPE, stdout=PIPE,
bufsize=1, # line-buffering
universal_newlines=True) # enable text mode
p.stdout.readline() # discard welcome message: "This program gener...
readchar = lambda: p.stdout.read(1)
def read_until(char):
buf = []
for c in iter(readchar, char):
if not c: # EOF
break
buf.append(c)
else: # no EOF
buf.append(char)
return ''.join(buf).strip()
prompt = read_until(':') # read 1st prompt
lo, hi = 0, 100
while lo <= hi:
mid = (lo + hi) // 2
print(prompt, mid)
print(mid, file=p.stdin) # send number
prompt = read_until(':') # read prompt
if "Congratulations" in prompt:
print(prompt)
print(mid)
break # found
elif "too high" in prompt:
hi = mid - 1 # guess > num
elif "too low" in prompt:
lo = mid + 1 # guess < num
else:
print('not found')
p.kill()
for pipe in [p.stdin, p.stdout]:
try:
pipe.close()
except OSError:
pass
sys.exit(p.wait())
Ich bin mir ziemlich sicher, dass das Hinzufügen von Zeilenumbrüchen in Ihrem C++-Programm dazu führt, dass die Readlines zurückgegeben werden.
Ja, aber ich möchte in der Lage sein, Skripte für vorhandene Programme zu erstellen, anstatt Programme an die Skripte anzupassen
– Ryan Haining
26. Oktober 11 um 1:25 Uhr
Es gibt keine generische Möglichkeit, EOF-Probleme zu “lösen”. Woher wissen Sie sonst, dass die Leitung tatsächlich zu Ende ist? Wenn Sie das Programm kennen, lesen Sie nicht bis zu einem Zeilenumbruch, lesen Sie einfach die genaue Anzahl an Zeichen, die Sie benötigen. Andernfalls geben Sie einen Zeilenumbruch zurück. Ihre andere Alternative ist die Verwendung von Zeitüberschreitungen, was wirklich schlecht ist.
– Ron Reiter
2. November 11 um 7:14 Uhr
Sie müssen nicht den genauen Betrag lesen. Es reicht aus, wenn Sie fast synchron sind (OS-Pipe-Puffer bietet Toleranz).
– jfs
22. Mai 14 um 0:28 Uhr
Möglicherweise müssen Sie explizit schließenstdinsodass der untergeordnete Prozess aufhört zu hängen, was meiner Meinung nach mit Ihrem Code passiert – dies kann überprüft werden, indem Sie top auf einem Terminal ausführen und prüfen, ob randomnumberDer Status von bleibt im Ruhezustand und wenn es nach der erwarteten Zeit, die es für die Ausführung benötigen würde, 0 % CPU verwendet.
Kurz gesagt, wenn Sie hinzufügen rng.stdin.close() gleich nach dem rng=subprocess(...) anrufen, kann es ohne Probleme fortgesetzt werden. Eine andere Option wäre zu tun output=rng.communicate(stdin="%dn" % i)und anschauen output[0]undoutput[1]wer sind stdout und stderr, bzw. Infos findest du untercommunicateHier.
Wow, ich habe vergessen, dass es diese Frage gibt. Wenn Sie stdin schließen, können Sie nicht mehr mit dem Prozess kommunizieren, was in diesem Fall erforderlich ist, um dynamisch auf die Ausgabe zu reagieren
– Ryan Haining
20. Mai ’14 um 14:39 Uhr
Exakt. Ich denke, Sie sollten der Antwort vielleicht ein Update hinzufügen, damit andere Leser die wahre Ursache des Aufhängens verstehen, was höchstwahrscheinlich der Grund ist, warum sie jemals hier ankommen. Außerdem hätte ich nichts dagegen, wenn Sie meine Antwort verbessern würden 🙂
– Lord Henry Wotton
20. Mai ’14 um 17:22 Uhr
@RyanHaining: Ihr C++-Code überprüft EOF auf stdin nicht und ruft daher auf rng.stdin.close() führt in Ihrem Fall vorzeitig zu einer Endlosschleife. ich würde … benutzen pexpect oder in diesem Fall sein Windows-Analogon.
– jfs
21. Mai 14 um 23:39 Uhr
@RyanHaining +1 für das Zitieren pexpect, was für mich völlig neu ist und für andere Leser vielleicht auch sein könnte. Würde es Ihnen etwas ausmachen, näher darauf einzugehen, wie es bei dem gegebenen Problem helfen würde?
– Lord Henry Wotton
22. Mai ’14 um 14:52 Uhr
@LordHenryWotton Ich glaube nicht, dass du mich damit markieren wolltest, aber JF Sebastian hat eine vollständige Antwort gepostet, die ausführlicher ist
– Ryan Haining
22. Mai ’14 um 15:10 Uhr
.
5715700cookie-checkUnterprozess readline hängt und wartet auf EOFyes