2017-04-19 16 views
5

Przez większość mojego życia używałem cstdio. Teraz próbuję przejść na iostream.Uruchom plik .exe i przekieruj standardowe wejście i wyjście

Załóżmy, że mam osobny program o nazwie "foo.cpp", który wygląda tak:

int main(){ // foo.cpp 
    int x; 
    std::cin >> x; 
    std::cout << x + 5 << "\n"; 
} 

w innym programie o nazwie "bar.cpp" wzywam wykonywalny foo. W przeszłości, gdybym chciał przekierować stdin i stdout do pliku, użyłbym freopen tak:

int main(){ // bar.cpp, redirecting stdin and stdout 
    freopen("foo.in", "r", stdin); // Suppose "foo.in" contains a single integer "42" 
    freopen("foo.out", "w", stdout); 

    system("foo.exe"); // "foo.out" will contain "47" 
} 

Teraz próbuję przekierować std::cin i std::cout do stringstreams. Coś takiego:

int main(){ // bar.cpp, redirecting cin and cout 
    std::istringstream instr("62"); 
    std::ostringstream outstr; 

    std::cin.rdbuf(instr.rdbuf()); 
    std::cout.rdbuf(outstr.rdbuf()); 

    system("foo.exe"); // outstr should contain "67" 
} 

Ale czego się nauczyłem, że std::cin i std::cout nie został przekierowany podczas wykonywania „foo.exe”. Program oczekuje teraz wprowadzenia użytkownika i wydrukuje do std::cout. Po wykonaniu "foo.exe", std::cin i w obrębie "bar.cpp" nadal pozostały przekierowane odpowiednio do instr i .

Moje pytanie brzmi, czy jest jakiś sposób, aby to zrobić z iostream, tak jak zamierzałem, czy utknąłem przy użyciu freopen?

+1

System operacyjny odpowiada za przetwarzanie danych wyjściowych plików wykonywalnych. Język C++ nie ma możliwości przekierowania wyjścia. –

+1

Typowe rozwiązania do dzielenia danych między programami: pliki, gniazda, orurowanie (powiedz systemowi operacyjnemu wyjście potoku innego programu na standardowe wejście dla twojego programu), obszary pamięci współużytkowanej. Przeszukaj internet. –

+1

Czy próbowałeś już wykonywać te same połączenia freopen? – stark

Odpowiedz

1

Nie widziałem połączenia freopen przez jakiś czas. To przywraca stare wspomnienia.

W każdym razie myślę, że powinieneś trzymać się z freopen. documentation strona funkcji dosłownie stwierdza, że ​​jest to jeden z głównych przypadków użycia:

Funkcja ta jest szczególnie przydatna do przekierowywania strumieni predefiniowanych jak stdin, stdout i stderrdo określonych plików.

Nie sądzę, można zrobić przekierowanie tylko iostream, ponieważ biblioteka iostream nie ma odpowiednika dla funkcji freopen.

To ciekawe, chociaż dlaczego to rozwiązanie próbowałeś nie działa:

std::cin.rdbuf(instr.rdbuf()); 
std::cout.rdbuf(outstr.rdbuf()); 

Może z tych dwóch liniach po prostu wpłynąć na rdbuf z std::cin i std::cout od bieżącego procesu i podproces ma inny wystąpienie std::cin i std::cout.

Informacje o plikach wydają się być kopiowane z procesu nadrzędnego do podprocesu podczas wywoływania system. Dlatego zmiany dokonane w głównym procesie na stdin i stdout z freopen są również widoczne w podprocesie.

Bez względu na to, you should not use system, aby uruchomić podprogram z głównego programu C++.Ponieważ prawdopodobnie jesteś w systemie Windows (zgadywanie z foo.exe), przeanalizowałbym ten plik example firmy Microsoft. Wyjaśnia, jak utworzyć podproces i użyć potoków do przekierowania wejścia i wyjścia podprogramu.

0

W swoim przykładowym kodzie za pomocą freopen, przekierowujesz do/z plików fizycznych, prawda? W twoim przykładowym kodzie za pomocą std :: istringstream i std :: ostringstream próbujesz przekierować do/z pamięci, prawda? Pliki fizyczne nie są tym samym co pamięć. Pamięć nie ma deskryptorów plików. W Linuksie możesz używać fmemopen jak w windows - C - create file in memory - Stack Overflow, ale to nie pomoże klasom standardowym C++, takim jak std :: istringstream i std :: ostringstream, ani nie będziesz w stanie przekierować stdin i stdout do/z fmemopen, na przykład dlatego, że fmemopen nie jest dostępny we wszystkich systemach operacyjnych. Standardowe klasy C++ nie obsługują tego typu rzeczy; patrz c++ - Getting a FILE* from a std::fstream - Stack Overflow. std :: istream i std :: ostream mogą wyglądać jak std :: istringstream i std :: ostringstream na poziomie C++, ale wewnętrznie nie są kompatybilne.

Powiązane problemy