2011-10-18 23 views
11

Bir C++ uygulaması yazıyorum ve bir sistem komutunun sonucunu okumam gerekiyor. Ben farklı bir şekilde bu yeniden yazmaya çalışıyorumC++ okuma sonuçları C++

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); 
    } 

: Burada gösterilen gibi popen() az ya da çok kullanıyorum

.

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

Benim derleyici bu olsa kabul etmiyor: Ben gibi bazı standart dışı çözümler gördü.

C++ 'da popen'dan nasıl okurum?

+0

Tüm kodum nedir? İlk çözümünüz, "data.append (buffer);" ise mükemmel çalışır. – Beta

+1

Arama yığınını kazandığınız yerden yayınlayabilir misiniz? – Arkadiy

+0

Lütfen hatayı gösteren bir minimum ** tamam ** programı sağlayın. Gerçek programla başla, işe yarayan bütün satırları sil ve sadece ne olduğunu göster. [Here] (http://ideone.com/azOcT), ilk kod parçanızın çalışan bir uygulamasının bir sınavıdır. Bu tekniği kullanma hakkında daha fazla bilgi için http://sscce.org adresini ziyaret edin. –

cevap

15

Sizin örnek:

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

does't iş size çok yakınız rağmen standart kütüphane bir FILE* inşa edilebilir bir fstream sağlamaz çünkü. Boost iostreams, bir dosya tanıtıcısından oluşturulabilen bir iostream sağlar ve fileno'u arayarak FILE*'dan bir tane alabilirsiniz.

Örn .:

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)) 

hala sonradan pclose unutmayın.

Not: Yükseltme işleminin daha yeni sürümleri, yalnızca fd numaralı telefonu alan kurumu kullanımdan kaldırmıştır. Bunun yerine, kurucuya zorunlu ikinci bir argüman olarak boost::iostreams::never_close_handle veya boost::iostreams::close_handle'dan birini geçirmeniz gerekir.

+0

Bazı derleyiciler standart C++ kütüphanesine standart olmayan uzantılar sağlar. Bir FILE * alan bir fstream kurucusu popüler bir tanesidir. Hangi neden bazı derleyiciler üzerinde çalışıyor ve diğerleri üzerinde değil açıklar. – Sjoerd

+0

@Sjoerd - ah evet bu mantıklı olurdu. Neden böyle yazılacağını merak ettim. Yine de, standart olmayan bir uzantı ile oluşturma aracınızdaki yapılandırma zamanında bir destek kitaplığı arasında seçim yapmak için bir yazım hatası kullanabilirsiniz. – Flexo

+1

fstream için standart kurucu ile çalıştı ama benim durumumda kabul edilmedi. Şimdi bu şekilde deneyeceğim ... – Stefano

-5

Uzun zamandır yazdığım, size yardımcı olabilecek bir şey. Bazı hatalar olabilir.

#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; 
     } 

}