2009-11-05 2 views

답변

4

표준 방법은 없지만 빠른 해결책을 원하면 fileno()를 사용하여 파일 설명자를 얻은 다음 Josuttis의 fdstream을 사용할 수 있습니다. 비슷한 노력이있을 수 있지만 나는 먼 과거에 이것을 사용했고 그것은 잘 동작했다. 아무것도 없다면 자신 만의지도를 구현할 수있는 아주 좋은지도 여야합니다.

1

확실한 방법이 있습니다. FILE*에서 생성 할 수있는 자신의 istream을 구현하십시오.

표준 방법이 있는지 묻는다면, 아니오.

13

std :: basic_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; 
} 
+0

+1 매우 유용합니다! 잘 했어 :-) – jweyrich