【问题标题】:Mapping UNIX Pipe to C++ std::cout将 UNIX 管道映射到 C++ std::cout
【发布时间】:2017-05-23 16:37:03
【问题描述】:

我正在研究在 C++ 中通信进程的选项。从将 Unix 管道绑定到 std::cout 的想法开始,但我可以让它工作。当直接使用 write(STDOUT_FILENO) 写入时,我得到了预期的结果。使用 std::cout 编写时,输出更小且随机。

#include <iostream>
#include <unistd.h>
#include <fcntl.h>

const int PIPE_READ = 0;
const int PIPE_WRITE = 1;

int main() {
    int pfd[2];

    if(pipe(pfd) == -1){
        std::cout << "Cannot create pipe" << std::endl;
        return 0;
    }
    int pid = fork();
    if(pid == -1){
        std::cout << "Error on fork: " << errno << std::endl;
    } else if(pid == 0) { // Child process
        if(dup2(pfd[PIPE_WRITE],STDOUT_FILENO) < 0) {
            std::cout << "Cannot redirect STDOUT: " << errno << std::endl;
            return 0;
        }
        close(pfd[PIPE_WRITE]);

        for(int i = 0; i < 8; i++){
            int data = i;
            write(STDOUT_FILENO,&data,sizeof(int)); // Works
            //std::cout << data; // Don't work
        }
    } else { // Parent process
        close(pfd[PIPE_WRITE]);
        for(int i = 0; i < 8; i++){
            int data;
            ssize_t status;
            if((status = read(pfd[PIPE_READ],&data,sizeof(int))) != sizeof(int)) {
                std::cout << "Error (" << errno << ") on read: " << status << std::endl;
                return -1;
            }
            std::cout << data << std::endl;
        }
    }
    return 0;
}

【问题讨论】:

    标签: c++ unix pipe stdout


    【解决方案1】:

    让我们仔细看看你的写作:

    write(STDOUT_FILENO,&data,sizeof(int)); // Works
    //std::cout << data; // Don't work
    

    第一个“工作”版本将data 的内容以原始二进制形式写入标准输出。第二个“非工作”版本将data 的值作为文本 写入标准输出。

    如果data 的值为5,则write 调用将写入整数值5,而std::cout &lt;&lt; data 将写入整数值53(使用ASCII encoding)。

    当您在父级中将数据作为原始和二进制 int 读取时,这当然会产生影响。

    如果要将原始二进制数据写入std::cout,则必须使用std::ostream::write

    std::cout.write(reinterpret_cast<char*>(&data), sizeof data);
    

    上面的行相当于你的write系统调用。


    同样重要的是要知道,以原始形式编写 int 将写入 sizeof(int) 字节,通常是四个。将一位整数作为文本写入将写入一个字节。

    您的循环将写入 8 个数字,这意味着如果使用 write,它将写入 32 个字节 (4 * 8)。如果您使用&lt;&lt; 输出到std::cout,那么您将写入 8 个字节。当您阅读时,您将读取这 8 个字节并放入两个单独的 int 值,然后 read 调用将返回 0,因为管道已关闭。

    这两个int 的值取决于您的硬件架构,如果是little-endian or big-endian

    【讨论】:

    • 小错误:)。我的假设是 cout 可以根据提供的数据类型输出字符串和二进制数据。另一个问题是文件描述符的变化没有反映在 C++ std::cout 对象中。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-28
    • 2014-09-17
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-15
    相关资源
    最近更新 更多