Supponiamo che "popen" un eseguibile, ottengo in cambio un FILE*
. Inoltre, supponiamo che mi piacerebbe "connettere" questo file ad un oggetto istream
per una più facile elaborazione, c'è un modo per farlo?FILE * e istream: collegare i due?
8
A
risposta
4
Non esiste un metodo standard, ma se si desidera una soluzione rapida è possibile ottenere il descrittore di file con fileno() e quindi utilizzare l'fdstream di Josuttis. Potrebbero esserci sforzi simili in giro ma l'ho usato in passato e ha funzionato bene. Se non altro dovrebbe essere una buona mappa per implementare la tua.
1
Certo che c'è un modo, implementare il proprio istream
che può essere costruito da un FILE*
.
Se stai chiedendo se esiste un modo standard per farlo, allora no.
13
Si può ottenere derivando classi std :: basic_streambuf o std :: streambuf.
Qualcosa in questo modo:
#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;
}
Problemi correlati
- 1. C++ e JMS - come collegare i due?
- 2. istream e memoria mappano un file?
- 3. Trascinare e rilasciare file virtuali utilizzando IStream
- 4. Come collegare due file sorgente nasm
- 5. C# IStream implementazione di IStream
- 6. Android.mk - Come assemblare e collegare i file assembler ARM
- 7. Come posso collegare i file xaml e xaml.cs
- 8. Collegare due applicazioni Meteor usando DDP
- 9. istream :: getline tipo restituito
- 10. Converti ifstream in istream
- 11. Collegare due telefoni Android con cavo USB
- 12. Problema API Jira Collegare due istanze diverse
- 13. È possibile collegare insieme due draggables jquery.ui?
- 14. Qt collegare due segnali insieme utilizzando QueuedConnection
- 15. Come collegare io.Reader e io.Writer?
- 16. come collegare i file di intestazione in C++
- 17. come collegare i file css nelle pagine di github dell'organizzazione
- 18. Come collegare un file (NodeJS)
- 19. Come collegare i fagioli interdipendenti in primavera?
- 20. Salta righe in std :: istream
- 21. Boost.Python e CMake collegare e caricare errori
- 22. C++ avvertimento risolvere IStream :: tellg
- 23. Confronta due file e scrivilo nei file "match" e "nomatch"
- 24. GStreamer: come collegare i pad dinamici
- 25. Copia veloce controllata da istream a ostream
- 26. Android - collegare i dati alle viste
- 27. discrepanza di istream eof tra libC++ e libstdC++
- 28. Come collegare file oggetto C++ con ld
- 29. Come trovare due abbinati ID in due file, e quindi utilizzare i loro valori per calcolare
+1 Abbastanza utile! Molto bene :-) – jweyrich