2011-10-18 31 views
11

Tôi đang viết một ứng dụng C++ và tôi cần đọc kết quả của lệnh hệ thống.Đọc kết quả popen bằng C++

Tôi đang sử dụng popen() nhiều hơn hoặc ít hơn như trình bày ở đây:

const int MAX_BUFFER = 2048; 
    string cmd="ls -l"; 
    char buffer[MAX_BUFFER]; 
    FILE *stream = popen(cmd.c_str(), "r"); 
    if (stream){ 
     while (!feof(stream)) 
     { 
      if (fgets(buffer, MAX_BUFFER, stream) != NULL) 
      { 
       //here is all my code 
      } 
     } 
     pclose(stream); 
    } 

Tôi đã cố gắng để tái viết này theo một cách khác. Tôi đã thấy một số giải pháp không chuẩn như:

FILE *myfile; 
std::fstream fileStream(myfile); 
std::string mystring; 
while(std::getline(myfile,mystring)) 
{ 
    // .... Here I do what I need 
} 

Trình biên dịch của tôi không chấp nhận điều này.

Làm cách nào để đọc từ popen bằng C++?

+0

'Đây là mã của tôi' ở đây? Giải pháp đầu tiên của bạn hoạt động hoàn hảo nếu đó là 'data.append (buffer);'. – Beta

+1

Bạn có thể xuất bản ngăn xếp cuộc gọi từ sự cố không? – Arkadiy

+0

Vui lòng cung cấp chương trình ** hoàn chỉnh tối thiểu ** để minh họa lỗi của bạn. Bắt đầu với chương trình thực tế của bạn, xóa tất cả các dòng hoạt động và chỉ cho chúng tôi thấy những gì còn lại. [Ở đây] (http://ideone.com/azOcT) là một sự kiểm tra về việc triển khai thực hiện đoạn mã đầu tiên của bạn. Xem http://sscce.org để biết thêm thông tin về cách sử dụng kỹ thuật này. –

Trả lời

15

dụ của bạn:

FILE *myfile; 
std::fstream fileStream(myfile); 
std::string mystring; 
while(std::getline(myfile,mystring)) 

việc does't vì mặc dù bạn đang rất gần các thư viện chuẩn không cung cấp một fstream có thể được xây dựng từ một FILE*. Tuy nhiên, Boost iostreams cung cấp một số iostream có thể được tạo từ bộ mô tả tệp và bạn có thể lấy từ một số FILE* bằng cách gọi fileno.

ví dụ .:

typedef boost::iostreams::stream<boost::iostreams::file_descriptor_sink> 
     boost_stream; 

FILE *myfile; 
// make sure to popen and it succeeds 
boost_stream stream(fileno(myfile)); 
stream.set_auto_close(false); // https://svn.boost.org/trac/boost/ticket/3517 
std::string mystring; 
while(std::getline(stream,mystring)) 

Đừng quên pclose sau vẫn còn.

Lưu ý: Các phiên bản mới hơn của tăng đã không được dùng cho hàm tạo chỉ mất fd. Thay vào đó, bạn cần phải chuyển một trong số boost::iostreams::never_close_handle hoặc boost::iostreams::close_handle làm đối số thứ hai bắt buộc cho hàm tạo.

+0

Một số trình biên dịch cung cấp phần mở rộng không chuẩn cho thư viện C++ chuẩn. Một hàm tạo fstream có một FILE * là một hàm phổ biến. Điều này giải thích tại sao nó hoạt động trên một số trình biên dịch chứ không phải trên các trình biên dịch khác. – Sjoerd

+0

@Sjoerd - ah vâng có ý nghĩa. Tôi tự hỏi tại sao nó lại được viết như thế. Tuy nhiên, bạn có thể sử dụng một typedef để chọn giữa một phần mở rộng không chuẩn và một thư viện tăng cường thời gian cấu hình trong công cụ xây dựng của bạn. – Flexo

+1

tôi đã thử với hàm tạo tiêu chuẩn cho fstream nhưng không được chấp nhận trong trường hợp của tôi. Tôi sẽ thử ngay bây giờ theo cách này ... – Stefano

-5

Đây là thứ tôi đã viết từ lâu, có thể giúp bạn. Nó có thể có một số lỗi.

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

bool my_popen (const std::string& cmd,std::vector<std::string>& out) { 
    bool   ret_boolValue = true; 
    FILE*   fp; 
    const int  SIZEBUF = 1234; 
    char   buf [SIZEBUF]; 
    out = std::vector<std::string>(); 
    if ((fp = popen(cmd.c_str(), "r")) == NULL) { 
     return false; 
    } 
    std::string cur_string = ""; 
    while (fgets(buf, sizeof (buf), fp)) { 
     cur_string += buf; 
    } 
    out.push_back (cur_string.substr (0, cur_string.size() - 1)); 
    pclose(fp); 
    return true; 
} 
int main (int argc, char **argv) { 
     std::vector<std::string> output; 
     my_popen("ls -l > /dev/null ", output); 
     for (std::vector<std::string>::iterator itr = output.begin(); 
               itr != output.end(); 
               ++itr) { 
       std::cout << *itr << std::endl; 
     } 

} 
Các vấn đề liên quan