2011-03-10 14 views
14

Al programar con C-estilo de E/S a veces uso freopen() para volver a abrir la entrada estándar para propósitos de prueba de modo que no tengo que volver a escribir la entrada de una y otra. Me preguntaba si existe un equivalente para las transmisiones de C++ i/o. Además, sé que puedo usar pipes para redirigirlo en la línea de comandos/terminal/whateveritis pero me preguntaba si había una forma de hacerlo dentro de mi código (porque como pueden ver, no estoy muy bien informado sobre el cl/t/w).freopen() equivalentes para C++ arroyos

+0

¿Puede usted leer la misma información dos veces cuando se tiene dos descriptores de archivo de la misma corriente? Si no, siempre puede usar varias instancias de std :: cin en C++ – LumpN

+0

Posible duplicado de [¿Cómo redirigir cin y cout a los archivos?] (Http://stackoverflow.com/questions/10150468/how-to-redirect- cin-and-cout-to-files) – Vadzim

Respuesta

26

freopen también funciona con cin y cout. No hay necesidad de buscar algo nuevo.

freopen("input.txt", "r", stdin); // redirects standard input 
freopen("output.txt", "w", stdout); // redirects standard output 

int x; 
cin >> x; // reads from input.txt 
cout << x << endl; // writes to output.txt 

Editar: De C++ estándar 27.3.1:

El objeto cin entrada controles a partir de una memoria de flujo asociado con el stdin objeto, declarado en <cstdio>.

Así que de acuerdo a la norma, si redirigimos stdin también se redirigirá cin. Viceversa por cout.

+0

No, no es así. Este programa tiene un comportamiento indefinido. –

+0

@R .. Lo he usado muchas veces en Visual Studio y g ++ y no tengo ningún problema. ¿Podrías por favor explicar qué es exactamente lo que está mal con eso? – UmmaGumma

+0

El hecho de que algo funcione en una implementación no significa que sea válido en C++. La última vez que lo verifiqué fue que * en el mejor de los casos * se definió la implementación si los cambios a stdio eran visibles en el iostream correspondiente o viceversa, y posiblemente empeoraban. –

1

This publicación de grupos de noticias explora sus opciones.

Esto depende del sistema y el cartel no indicaba el sistema , pero cin.clear() debería funcionar. He probado el programa adjunto en un sistema UNIX con AT & versión T de iostreams.

#include <iostream.h> 
int main() 
{ 
    for(;;) { 
     if (cin.eof()) { 
      cout << "EOF" << endl; 
      cin.clear(); 
     } 
     char c ; 
     if (cin.get(c)) cout.put(c) ; 
    } 
} 

Sí, que funciona bien en cfront y TC++. En g ++ donde el problema surgió por primera vez una acción adicional se requiere:

cin.clear(); 
    rewind (_iob); // Seems quite out of place, doesn't it? 
        // cfront also accepts but doesn't 
        // require this rewind. 

Aunque observo que esto fue en 1991, debería seguir funcionando. Recuerde utilizar el encabezado iostream ahora estándar, no iostream.h.

(Por cierto he encontrado que post con los términos de búsqueda de Google "reabrir cin C++", segundo resultado.)

hacernos saber cómo le va. También podría simplemente usar freopen.

+0

Mezclar C stdio y C++ iostream el uso de este modo no es válido y dará como resultado un comportamiento definido por la implementación o indefinido. –

+0

Lo siento, realmente no entiendo cómo se relaciona esto con mi pregunta. ¿Podrías explicar más? – quasiverse

+0

@quasiverse: se trata de volver a abrir STDIN a través de 'cin'. –

14
#include <iostream> 
#include <fstream> 

int main() { 

    // Read one line from stdin 
    std::string line; 
    std::getline(std::cin, line); 
    std::cout << line << "\n"; 

    // Read a line from /etc/issue 
    std::ifstream issue("/etc/issue"); 
    std::streambuf* issue_buf = issue.rdbuf(); 
    std::streambuf* cin_buf = std::cin.rdbuf(issue_buf); 
    std::getline(std::cin, line); 
    std::cout << line << "\n"; 

    // Restore sanity and read a line from stdin 
    std::cin.rdbuf(cin_buf); 
    std::getline(std::cin, line); 
    std::cout << line << "\n"; 
} 

http://www.cplusplus.com/reference/iostream/ios/rdbuf/

Cuestiones relacionadas