C/C++

Передача данных в дочернюю программу и вывод из неё

Здравствуйте!
У меня есть 2 консольные программы, 1 изменять нельзя - она выводит данные и может принимать методом ввода, 2 надо написать так чтобы она могла запустить как дочернюю ту и принимать вывод той программы в память и отправлять данные из памяти. При этом делать это многократно без закрытия обоих программ.

Я уже пробовал делать это с помощью system("cmd"); но ничего не получается. Данные нужно передавать из памяти а не с клавиатуры. я перерыл кучу информации но так и не понял как это делать.

Вот пробный код что я сделал -

#include <iostream>
#include <cmath>
#include <string>
#include <conio.h>
#include <thread>
#include <windows.h>

using namespace std;

int main() {

cout << "Start" << endl;

string str;
string vivod;

int i = 0;
int j = 0;

for (i=0; i<j; j++) {
cin >> str;
system (vivod < "node index.js" < str);
cout << vivod << endl;
}


cout << "end" << endl;
return 0;
}
Это абсолютно не рабочий код из всей инфы что я нарыл в интернете, какие есть варианты выполнения данной задачи?
Если что это на windows так как всю инфу что нарыл на линукс убунту и так далее.
Значит так, есть несколько путей как это сделать разного уровня сложности.
Путь первый, простой:
 #include  
// Функция popen открывает неименованный канал (трубу, PIPE) к
// процессу command
FILE *popen(const char *command, const char *type);
// Функция pclose его закрывает.
int pclose(FILE *stream);
Внутри функции popen происходит большой объем работы, в частности при помощи функции pipe создается пара файловых дескрипторов, одни из которых служит для записи в однонаправленный канал передачи информации а другой для чтения из него. А потом один из дескрипторов отправляется в дочерний процесс для замены его стандартного ввода или вывода (что менять определяет параметр type).
Ниже пример программы, в котором строка из программы через канал поступает на вход команды wc. Данная команда считает количество строк, слов и байт из стандартного ввода и выводит это число в STDOUT.
 #include  

int main( int argc, char* argv[] )
{
FILE* fp;
// Откроем пипу к команде wc на запись
fp = popen("/usr/bin/wc", "w" );
if( fp )
{
// Записываем в канал строку "My string\n"
fprintf( fp, "My string\n" );
// Закрываем канал
pclose( fp );
}
else
{
perror("popen");
return 1;
}
return 0;
}
После запуска программы получается следующее:
 ./app_popen  
1 2 10
Если надо передать данные в программу, а потом считать их из нее обратно, то данный метод уже не подходит, так как popen открывает только одну пипу, а она однонаправленная. Тут надо будет руками создавать две пипы и менять в дочернем процессе STDIN и STDOUT на их файловые дескрипторы (см. функцию dup2). При этом надо иметь ввиду, что, при большом объеме передаваемых данных тут возмжно заиметь проблемы со взаимной блокировкой. Тут поможет либо выполнение, чтения и записи в разных потоках, либо использование функций типа select или poll
Андрей Брынцев
Андрей Брынцев
9 624
Лучший ответ
Андрей Брынцев Когда popen запускает команду на выполнение, она делает это через запуск оболочки, поэтому возможно использовать символы перенаправления потока.
Пример №2, в котором вывод команды wc перенаправляется на вход команды rev, которая меняет порядок байт в строке на обратный
 #include  

int main( int argc, char* argv[] )
{
FILE* fp;
// Откроем пипу к команде wc на запись
fp = popen("/usr/bin/wc | rev", "w" );
if( fp )
{
fprintf( fp, "My string\n" );
pclose( fp );
}
else
{
perror("popen");
return 1;
}
return 0;
}
Это можно использовать для того, чтобы ваша команда скидывала данные в дочернюю подпрограмму, а та, в свою очередь, запускала второй экземпляр вашей команды и скидывала обработанные данные ей на STDIN
Ну раз они консольные, то значит в 99% случаев есть перенаправление вывода в файл или на вход другой программе через |
Под Windows перенаправление тоже работает (есть конечно особенности).
"При этом делать это многократно без закрытия обоих программ. " - если вы первую НЕ можете изменить, как вы добьетесь изменения поведения первой программы?

Еще вариант - через временные файлы: первая программа кидает данные в определенный файл, вторая периодически ищет файлы по маске, если находит, то читает, исполняет написанное, выдает результат (тоже в определенный временный файл или через трубу |)
Жандос Кадырбаев *опечатка, 2 изменить нельзя а 1 можно
Жандос Кадырбаев 1 надо написать а 2 это среда выполнения java scrip - node.js
я много опечаток сделал просто спешил, сорян.
Жандос Кадырбаев там 2 программы на с++ у меня на с++ только 1 а 2 среда выполнения java script её переписать нельзя
Сергей Баёв Как это типично для WinAPI - то что делается в две строчки растянуть на две страницы.