0

My QProcess is very simple and goes something like:

#include <iostream>
#include <string>

int main() {
std::string a, b;
std::cout<<"Enter value of a: ";
std::cin>>a;
std::cout<<std::endl;
std::cout<<"Now, enter value of b: ";
std::cin>>b;
std::cout<<std::endl;
std::cout<<"Value of a is "<<a<<" and value of b is "<<b<<std::endl;

return 0;
}

Note that I cannot change the above code. The Qt code should work regardless of the process.

So as far as I understood, QProcess::write(const char *data) [inherited from QIODevice] sends the data to the buffer but does not directly send it to the standard in, unless the write channel is closed, or the process has finished.

However, I need to send data to the standard in directly as I call QProcess::write(const char *data), because I cannot close the channel after the first std::cin, or else the second std::cin does not get anything. So I want to send the process some data as it asks for it [as if running this code on a command line], and I'm not sure how to do that with Qt.

Also, I don't think waitForBytesRead()would do good since it just waits aroundupon entering the first set of data to the buffer and the process is not continued.

QProcess-related code:

  QProcess my_proc = new QProcess();
  QString program = "powershell.exe";
  QStringList prog_args;
  prog_args << "-Command" << "./main"
  my_proc->setProcessChannelMode(QProcess::MergedChannels);
  my_proc->setProgram(program);
  my_proc->setArguments(prog_args);
  my_proc->start();
  my_proc->waitForStarted();

~The output of the program gets printed on a QTextBrowser, or any similar widget. So I know when it asks for the relevant inputs.~

~In another QTextEdit qinput or similar, I input the string I want to send to the process, and this is governed by:

if ( my_proc->state() == QProcess::Running) {
my_proc->write(qinput->toPlainText().toStdString().c_str());
}

~And from here nothing happens, so the line "Now enter the value of b" does not get displayed~

Mo Kanj
  • 107
  • 7

2 Answers2

2

No need to use ...toStdString().c_str() for such a cases when having QString and QByteArray.

Do the following:

if ( proc->state() == QProcess::Running) 
{
    proc->write(qinput->toPlainText().toUtf8() + "\n"); // as I understand, \n will flush the line
}

Note that you can also use proc->write("\n"); to simulate "press any key"

Vladimir Bershov
  • 2,701
  • 2
  • 21
  • 51
  • Yes, that was exactly missing.. many thanks! Do you think adding the newline character is a cross-platform solution relative to where the Qt gui is run and relative to the main process if it were written in another programming language? – Mo Kanj Sep 21 '20 at 15:59
  • @MoKanj as I can understand, yes, it is crossplatform. See also https://stackoverflow.com/a/27620074/4149835 – Vladimir Bershov Sep 21 '20 at 16:05
  • However, appending the newline character `\n` renders the input taken, but does not actually put a new line. Is there a workaround other than appending `\n\n` [because this does not work]? – Mo Kanj Sep 22 '20 at 10:38
  • @MoKanj see this - https://stackoverflow.com/a/36738723/4149835 – Vladimir Bershov Sep 22 '20 at 13:54
  • So appending `\n` to C++ based processes works; however, it did not do the job for a similarly written C# console app. It just waits around after typing the first string... since I'm not that knowledgeable in C#, do you have any idea how things work there? – Mo Kanj Sep 23 '20 at 09:12
  • @MoKanj no, I have no experience in c # either – Vladimir Bershov Sep 23 '20 at 22:07
0

you can try flushing stdin stream:

fflush(stdin);

or use getline:

std::string myString;
std::getline(std::cin, myString);

this will end reading when (newline char) is typed

  • The thing is is that I'm not allowed to edit the QProcess main code. So I want the Qt code to work regardless of the process's main code. – Mo Kanj Sep 21 '20 at 15:42
  • 2
    Flushing an input stream is [undefined behavior](https://stackoverflow.com/questions/2979209/using-fflushstdin). – bnaecker Sep 21 '20 at 15:43