Câu hỏi này sau từ nỗ lực của tôi để thực hiện các hướng dẫn trong:Piping cho đầu vào/đầu ra
Linux Pipes as Input and Output
How to send a simple string between two programs using pipes?
http://tldp.org/LDP/lpg/node11.html
Câu hỏi của tôi là dọc theo dòng của câu hỏi trong: Linux Pipes as Input and Output, nhưng cụ thể hơn.
Về cơ bản, tôi đang cố gắng để thay thế:
/directory/program <input.txt> output.txt
sử dụng đường ống trong C++ để tránh sử dụng ổ cứng. Đây là mã của tôi:
//LET THE PLUMBING BEGIN
int fd_p2c[2], fd_pFc[2], bytes_read;
// "p2c" = pipe_to_child, "pFc" = pipe_from_child (see above link)
pid_t childpid;
char readbuffer[80];
string program_name;// <---- includes program name + full path
string gulp_command;// <---- includes my line-by-line stdin for program execution
string receive_output = "";
pipe(fd_p2c);//create pipe-to-child
pipe(fd_pFc);//create pipe-from-child
childpid = fork();//create fork
if (childpid < 0)
{
cout << "Fork failed" << endl;
exit(-1);
}
else if (childpid == 0)
{
dup2(0,fd_p2c[0]);//close stdout & make read end of p2c into stdout
close(fd_p2c[0]);//close read end of p2c
close(fd_p2c[1]);//close write end of p2c
dup2(1,fd_pFc[1]);//close stdin & make read end of pFc into stdin
close(fd_pFc[1]);//close write end of pFc
close(fd_pFc[0]);//close read end of pFc
//Execute the required program
execl(program_name.c_str(),program_name.c_str(),(char *) 0);
exit(0);
}
else
{
close(fd_p2c[0]);//close read end of p2c
close(fd_pFc[1]);//close write end of pFc
//"Loop" - send all data to child on write end of p2c
write(fd_p2c[1], gulp_command.c_str(), (strlen(gulp_command.c_str())));
close(fd_p2c[1]);//close write end of p2c
//Loop - receive all data to child on read end of pFc
while (1)
{
bytes_read = read(fd_pFc[0], readbuffer, sizeof(readbuffer));
if (bytes_read <= 0)//if nothing read from buffer...
break;//...break loop
receive_output += readbuffer;//append data to string
}
close(fd_pFc[0]);//close read end of pFc
}
Tôi hoàn toàn chắc chắn rằng các chuỗi ở trên được khởi tạo đúng cách. Tuy nhiên, hai điều xảy ra không hợp lý với tôi:
(1) Chương trình tôi đang thực hiện báo cáo rằng "tệp đầu vào trống." Vì tôi không gọi chương trình với "<" nên không nên mong đợi tệp đầu vào. Thay vào đó, nó sẽ được mong đợi đầu vào bàn phím. Hơn nữa, nó nên được đọc văn bản chứa trong "gulp_command."
(2) Báo cáo của chương trình (được cung cấp qua đầu ra tiêu chuẩn) xuất hiện trong thiết bị đầu cuối. Điều này là kỳ lạ vì mục đích của đường ống này là chuyển stdout thành chuỗi của tôi "receive_output". Nhưng vì nó xuất hiện trên màn hình, điều đó cho tôi biết rằng thông tin không được truyền chính xác qua đường ống đến biến đó. Nếu tôi triển khai các điều sau ở cuối câu lệnh if,
cout << receive_output << endl;
Tôi không nhận được gì, như chuỗi rỗng. Tôi đánh giá cao bất kỳ giúp bạn có thể cho tôi!
CHỈNH SỬA: Làm rõ
Chương trình của tôi hiện đang giao tiếp với một chương trình khác bằng tệp văn bản. Chương trình của tôi viết một tệp văn bản (ví dụ: input.txt), được chương trình bên ngoài đọc. Chương trình đó sau đó tạo output.txt, được đọc bởi chương trình của tôi. Vì vậy, nó là một cái gì đó như thế này:
my code -> input.txt -> program -> output.txt -> my code
Do đó, mã của tôi hiện đang sử dụng,
system("program <input.txt> output.txt");
Tôi muốn thay thế quá trình này sử dụng ống. Tôi muốn chuyển đầu vào của tôi như là đầu vào tiêu chuẩn cho chương trình, và có mã của tôi đọc đầu ra tiêu chuẩn từ chương trình đó thành một chuỗi.
Đề xuất bắt đầu của bạn không rõ ràng. Bạn nói rằng bạn muốn thay thế '/ directory/program output.txt' bằng một cái gì đó bằng cách sử dụng đường ống để tránh truy cập hệ thống tập tin. Nhưng bạn cần 'nhiều quy trình để sử dụng ống hợp lý. (Bạn _can_ sử dụng đường ống trong một quá trình duy nhất, nhưng nó không có ý nghĩa thường.) Vì vậy, bạn có thể có '/ directory/program1 output.txt'; có ý nghĩa (và trước đó bạn có thể đã sử dụng '/ directory/program1 intermediate.txt;/directory/program2 output.txt'). Vui lòng làm rõ ý định của bạn. –
Điểm tốt. Tôi đã chỉnh sửa câu hỏi. –
Làm rõ thêm, mục tiêu của tôi về cơ bản giống như câu hỏi trong: stackoverflow.com/questions/1734932/… mà bạn đã trả lời trước đây (câu trả lời tuyệt vời bằng cách này). –