簡體   English   中英

如何從另一個程序運行程序並通過 c 或 c++ 中的 stdin 將數據傳遞給它?

[英]How do I run a program from another program and pass data to it via stdin in c or c++?

假設我有一個.exe ,讓我們說sum.exe 現在說sum.exe的代碼是

void main ()
{
 int a,b;
 scanf ("%d%d", &a, &b);
 printf ("%d", a+b);
}

我想知道如何從另一個 c/c++ 程序運行這個程序並通過 stdin 傳遞輸入,就像他們在 ideone 等在線編譯器站點中所做的那樣,我在其中鍵入代碼並在文本框中提供 stdin 數據,並且該數據被接受該程序使用 scanf 或 cin。 另外,我想知道是否有任何方法可以從啟動它的原始程序中讀取該程序的輸出。

在名稱以 X 結尾的平台(即不是 Windows)上的 C 中,關鍵組件是:

  1. pipe - 返回一對文件描述符,以便可以從另一個讀取寫入其中的內容。

  2. fork - 將進程fork為兩個,兩個都繼續運行相同的代碼。

  3. dup2 - 重新編號文件描述符。 有了這個,您可以將管道的一端轉換為標准輸入或標准輸出。

  4. exec - 停止運行當前程序,在同一進程中開始運行另一個程序。

將它們全部結合起來,您就可以獲得所需的東西。

我知道的最簡單的方法是使用popen()函數。 它適用於 Windows 和 UNIX。 另一方面, popen()只允許單向通信。

例如,要將信息傳遞給sum.exe (雖然您將無法讀回結果),您可以這樣做:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *f;

    f = popen ("sum.exe", "w");
    if (!f)
    {
        perror ("popen");
        exit(1);
    }

    printf ("Sending 3 and 4 to sum.exe...\n");
    fprintf (f, "%d\n%d\n", 3, 4);

    pclose (f);
    return 0;
}

這是我的解決方案,它有效:

總和文件

#include "stdio.h"
int main (){
  int a,b;
  scanf ("%d%d", &a, &b);
  printf ("%d", a+b);
  return 0;
}

測試.cpp

#include <stdio.h>
#include <stdlib.h>

int main(){
  system("./sum.exe < data.txt");
  return 0;
}

數據.txt

3 4

試試這個解決方案:)

聽起來您來自 Windows 環境,所以這可能不是您正在尋找的答案,但是從命令行您可以使用管道重定向運算符“|” 將一個程序的標准輸出重定向到另一個程序的標准輸入。 http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/redirection.mspx?mfr=true

你可能最好在 bash shell 中工作,你可以在 Windows 上使用 cygwin http://cygwin.com/

此外,您的示例看起來像是 C++ 和 C 的混合體,並且 main 的聲明並不完全是公認的標准。

如何做到這一點取決於平台。

在 windows 下,使用 CreatePipe 和 CreateProcess。 您可以從 MSDN 找到示例: http : //msdn.microsoft.com/en-us/library/windows/desktop/ms682499 (v= vs.85).aspx

在 Linux/Unix 下,您可以使用dup() / dup2()

一種簡單的方法是使用終端(如 Windows 中的命令提示符)並使用 | 重定向輸入/輸出。

例子:

program1 | program2

這會將程序 1 的輸出重定向到程序 2 的輸入。 要檢索/輸入日期,您可以使用臨時文件,如果您不想使用臨時文件,則必須使用管道。

對於 Windows,(使用命令提示符):

program1 <input >output 

對於 Linux,您可以使用tee實用程序,您可以通過在 linux 終端中鍵入man tee來查看詳細說明

如何執行此操作(您必須檢查錯誤,即pipe()==-1dup()!=0等,我不會在以下代碼段中執行此操作)。

此代碼運行您的程序“sum”,向其寫入“2 3”,然后讀取 sum 的輸出。 接下來,它將輸出寫入標准輸出。

#include <iostream>
#include <sys/wait.h>
#include <unistd.h>

int main() {

    int parent_to_child[2], child_to_parent[2];
    pipe(parent_to_child);
    pipe(child_to_parent);

    char name[] = "sum";
    char *args[] = {name, NULL};
    switch (fork()) {

    case 0:
        // replace stdin with reading from parent
        close(fileno(stdin));
        dup(parent_to_child[0]);
        close(parent_to_child[0]);

        // replace stdout with writing to parent
        close(fileno(stdout));
        dup(child_to_parent[1]);
        close(child_to_parent[1]);

        close(parent_to_child[1]); // dont write on this pipe
        close(child_to_parent[0]); // dont read from this pipe

        execvp("./sum", args);
        break;

    default:
        char msg[] = "2 3\n";

        close(parent_to_child[0]); // dont read from this pipe
        close(child_to_parent[1]); // dont write on this pipe

        write(parent_to_child[1], msg, sizeof(msg));
        close(parent_to_child[1]);

        char res[64];
        wait(0);
        read(child_to_parent[0], res, 64);
        printf("%s", res);
        exit(0);
    }
}

我正在做@ugoren在他們的回答中建議的事情:

  • 創建兩個管道用於進程之間的通信
  • 叉子
  • 使用dup用管道末端替換 stdin 和 stdout
  • 通過管道發送數據

根據上面發布的一些答案和各種教程/手冊,我只是在 Linux 中使用pipe()和 shell 重定向來完成此操作。 策略是先創建一個管道,調用另一個程序並將被調用者的輸出從stdout重定向到管道的一端,然后再讀取管道的另一端。 只要被調用者寫入stdout ,就不需要修改它。

在我的應用程序中,我需要讀取用戶輸入的數學表達式,調用獨立計算器並檢索其答案。 這是我演示重定向的簡化解決方案:

#include <string>
#include <unistd.h>
#include <sstream> 
#include <iostream> 

// this function is used to wait on the pipe input and clear input buffer after each read    
std::string pipeRead(int fd) { 
    char data[100];
    ssize_t size = 0;
    while (size == 0) {
        size = read(fd, data, 100);
    }
    std::string ret = data;
    return ret;
}

int main() {
    // create pipe
    int calculatorPipe[2];
    if(pipe(calculatorPipe) < 0) {
        exit(1);
    }
    
    std::string answer = "";
    std::stringstream call;

    // redirect calculator's output from stdout to one end of the pipe and execute
    // e.g. ./myCalculator 1+1 >&8
    call << "./myCalculator 1+1 >&" << calculatorPipe[1];
    system(call.str().c_str());

    // now read the other end of the pipe
    answer = pipeRead(calculatorPipe[0]);
    std::cout << "pipe data " << answer << "\n";

    return 0;
}

顯然還有其他解決方案,但這是我可以在不修改被調用程序的情況下想到的。 不過,Windows 中的情況可能有所不同。

一些有用的鏈接:

https://www.geeksforgeeks.org/pipe-system-call/

https://www.gnu.org/software/bash/manual/html_node/Redirections.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM