Załóżmy, że "popen" plik wykonywalny, otrzymuję w zamian FILE*
. Co więcej, przypuśćmy, że chciałbym "połączyć" ten plik z obiektem istream
w celu łatwiejszego przetwarzania, czy jest na to jakiś sposób?PLIK * i istream: połączyć dwa?
8
A
Odpowiedz
4
Nie ma standardowej metody, ale jeśli chcesz uzyskać szybkie rozwiązanie, możesz uzyskać deskryptor pliku za pomocą fileno(), a następnie użyć Josuttis 'fdstream. Mogą być podobne wysiłki, ale użyłem tego w odległej przeszłości i wszystko działało dobrze. Jeśli nic innego, to powinna być bardzo dobra mapa do realizacji własnych.
1
Na pewno jest sposób, zaimplementuj własny istream
, który można skonstruować z FILE*
.
Jeśli pytasz, czy istnieje standardowy sposób, aby to zrobić, to nie.
13
Możesz uciec, wyprowadzając klasy std :: basic_streambuf lub std :: streambuf.
Coś w tym stylu:
#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;
}
Powiązane problemy
- 1. C# Implementacja IStream IStream
- 2. Jak połączyć dwa ArrayLists?
- 3. jak połączyć dwa LPCWSTRy?
- 4. C++ i JMS - jak połączyć te dwa?
- 5. Porównać (i połączyć) dwa projekty VS C#
- 6. Python - Połączyć dwa słowniki, połączyć wartości ciągów?
- 7. połączyć dwa pliki skumulowane GCC .o w trzeci plik .o
- 8. Jak połączyć dwa wchar_t * razem?
- 9. Jak połączyć dwa wyniki jQuery
- 10. Połączyć dwa wyniki w Powershell
- 11. Jak połączyć dwa atomy/łańcuchy?
- 12. Jak połączyć dwa SwiftyJSON obiektów
- 13. Jak połączyć dwa strumienie pamięci?
- 14. Jak połączyć dwa pliki tcpdump (pliki pcap)?
- 15. połączyć dwa pliki za pomocą awk
- 16. Dziedziczenie std :: istream lub równoważnego
- 17. Jak połączyć plik exe i msi w jednej konfiguracji?
- 18. jak połączyć dwa Zestawienia zmian tylko (TFS)
- 19. Jak połączyć dwa proci w jeden?
- 20. Jak połączyć dwa transformatory Boost Geometry?
- 21. Połączyć dwa numpy tablice w czwartym wymiarze
- 22. Jak połączyć dwa obiekty w JavaScript?
- 23. Jak połączyć dwa ResultSets w Javie?
- 24. Jak połączyć dwa plasterki w Rust?
- 25. Jak połączyć dwa lub więcej strumieni
- 26. Jak połączyć dwa generatory w Pythonie?
- 27. Połączyć dwa zapytania SELECT w PostgreSQL
- 28. Jak połączyć dwa ciągi (IO) w Haskell?
- 29. Jak połączyć dwa wyrażenia: result = exp1 (exp2);
- 30. Jak połączyć dwa wektory w ramce danych
+1 Bardzo przydatne! Dobra robota :-) – jweyrich