2009-07-09 6 views
1

Je souhaite lire la sortie std d'un appel système dans une chaîne C/C++. Puis-je le faire sans utiliser de fichier temporaire?Capture de stdout syscall sans écrire dans un fichier en C/C++

Perl

//without file io 
$output = `echo hello`; 

C++

//with file io 
system ("echo hello > tmp"); 
std::fstream file ("tmp"); 
std::string s; 
file >> s; 
+5

http://stackoverflow.com/questions/646868/how-can-i-capture-another-processs-output-using-c –

+3

Le le problème ici est bien entendu que "appel système" n'est pas le même qu'un "appel système()". – MSalters

+0

@alex vasi: merci pour le lien, j'ai fait une recherche mais je n'ai pas trouvé cette page avant de poster la question. – Akusete

Répondre

2

En utilisant popen (probablement la solution la plus simple, même si elle n'utilise pas de iostream C++) de C:

FILE *p = popen("echo hello", "r"); 
std::string s; 
for (size_t count; (count = fread(buf, 1, sizeof(buf), p));) 
    s += string(buf, buf + count); 
pclose(p); 

En supposant que votre iostream a le constructeur non standard xfstream::xfstream(int fd):

FILE *p = popen("echo hello", "r"); 
std::ifstream p2(fileno(p)); 
std::string s; 
p2 >> s; 
p2.close(); 
pclose(p); 

En utilisant Boost.Iostreams, vous n'avez pas à déformer nd sur des extensions non standard iostream:

boost::iostreams::file_descriptor_source p2(fileno(p)); 

Malheureusement, Windows est horrible et _popen ne fonctionne que pour les applications de la console; pour une application graphique:

SECURITY_ATTRIBUTES sec; 
sec.nLength = sizeof(sec); 
sec.bInheritHandle = TRUE; 
sec.lpSecurityDescriptor = NULL; 
HANDLE *h[2]; 
CreatePipe(&h[0], &h[1], &sec, 0); 
SetHandleInformation(h[0], HANDLE_FLAG_INHERIT, 0) 
STARTUPINFO si; 
memset((void *)&si, 0, sizeof(si)); 
si.hStdInput = INVALID_HANDLE_VALUE; 
si.hStdOutput = h[1]; 
si.hStdError = INVALUD_HANDLE_VALUE; 
si.dwFlags |= STARTF_USESTDHANDLES; 
CreateProcess(NULL, "cmd /c \"echo hello\"", NULL, NULL, TRUE, 0, NULL, NULL, &si, NULL); 
boost::iostreams::file_descriptor_source p(h[0]); 

(complètement non testé)

+0

Attendez ... vous appelez p2.close(), puis pclose() sur le même flux. Cela signifie que vous essayez de le fermer deux fois. Il me semble qu'une fois que vous l'avez passé à l'ifstream, vous perdez le contrôle de ce flux et vous ne pouvez plus utiliser p. –

0

This peut vous aider à rediriger stdout d'un appel système.

Questions connexes