Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 文件*和istream:将两者连接起来?_C++_Linux_Popen_Istream - Fatal编程技术网

C++ 文件*和istream:将两者连接起来?

C++ 文件*和istream:将两者连接起来?,c++,linux,popen,istream,C++,Linux,Popen,Istream,假设我“popen”一个可执行文件,我得到一个文件*。此外,假设我想将此文件“连接”到一个istream对象以便于处理,有没有办法做到这一点?当然有办法,实现您自己的istream,它可以从文件*构建 如果您询问是否有标准的方法来执行此操作,则答案是否定的。没有标准的方法,但如果您需要快速解决方案,可以使用fileno()获取文件描述符,然后使用Josuttis'。可能也有类似的努力,但我在遥远的过去使用过,效果很好。如果没有其他东西,它应该是实现您自己的类的一个很好的映射。您可以通过派生std

假设我“popen”一个可执行文件,我得到一个
文件*
。此外,假设我想将此文件“连接”到一个
istream
对象以便于处理,有没有办法做到这一点?

当然有办法,实现您自己的
istream
,它可以从
文件*
构建


如果您询问是否有标准的方法来执行此操作,则答案是否定的。

没有标准的方法,但如果您需要快速解决方案,可以使用fileno()获取文件描述符,然后使用Josuttis'。可能也有类似的努力,但我在遥远的过去使用过,效果很好。如果没有其他东西,它应该是实现您自己的类的一个很好的映射。

您可以通过派生std::basic\u streambuf或std::streambuf类来摆脱
大致如下:

#include <stdio.h>
#include <iostream>

#define BUFFER_SIZE     1024

class popen_streambuf : public std::streambuf {
public:
    popen_streambuf() : fp(NULL) {
    }
    ~popen_streambuf() {
        close();
    }
    popen_streambuf *open(const char *command, const char *mode) {
        fp = popen(command, mode);
        if (fp == NULL)
            return NULL;
        buffer = new char_type[BUFFER_SIZE];
        // It's good to check because exceptions can be disabled
        if (buffer == NULL) {
            close();
            return NULL;
        }
        setg(buffer, buffer, buffer);
        return this;
    }
    void close() {
        if (fp != NULL) {
            pclose(fp);
            fp = NULL;
        }
    }
    std::streamsize xsgetn(char_type *ptr, std::streamsize n) {
        std::streamsize got = showmanyc();
        if (n <= got) {
            memcpy(ptr, gptr(), n * sizeof(char_type));
            gbump(n);
            return n;
        }
        memcpy(ptr, gptr(), got * sizeof(char_type));
        gbump(got);

        if (traits_type::eof() == underflow()) {
            return got;
        }
        return (got + xsgetn(ptr + got, n - got));
    }
    int_type underflow() {
        if (gptr() == 0) {
            return traits_type::eof();
        }
        if (gptr() < egptr()) {
            return traits_type::to_int_type(*gptr());
        }
        size_t len = fread(eback(), sizeof(char_type), BUFFER_SIZE, fp);
        setg(eback(), eback(), eback() + (sizeof(char_type) * len));
        if (0 == len) {
            return traits_type::eof();
        }
        return traits_type::to_int_type(*gptr());
    }
    std::streamsize showmanyc() {
        if (gptr() == 0) {
           return 0;
        }
        if (gptr() < egptr()) {
            return egptr() - gptr();
        }
        return 0; 
    }
private:
    FILE *fp;
    char_type *buffer;
};

int main(int argc, char *argv)
{
    char c;
    popen_streambuf sb;
    std::istream is(&sb);

    if (NULL == sb.open("ls -la", "r")) {
        return 1;
    }

    while (is.read(&c, 1)) {
        std::cout << c;
    }

    return 0;
}
#包括
#包括
#定义缓冲区大小1024
类popen_streambuf:public std::streambuf{
公众:
popen_streambuf():fp(NULL){
}
~popen_streambuf(){
close();
}
popen_streambuf*打开(常量字符*命令,常量字符*模式){
fp=popen(命令、模式);
如果(fp==NULL)
返回NULL;
缓冲区=新字符类型[缓冲区大小];
//检查很好,因为可以禁用异常
if(buffer==NULL){
close();
返回NULL;
}
setg(缓冲器,缓冲器,缓冲器);
归还这个;
}
无效关闭(){
如果(fp!=NULL){
pclose(fp);
fp=NULL;
}
}
std::streamsize xsgetn(字符类型*ptr,std::streamsize n){
std::streamsize get=showmanyc();
如果(n)