Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

300
Visualizações
Cómo redirigir la salida del programa como su entrada

He escrito un programa simple en C++ con fines de tutorial. Mi objetivo es repetirlo infinitamente.

 #include <iostream> #include <string> int main() { std::cout << "text"; for(;;) { std::string string_object{}; std::getline(std::cin, string_object); std::cout << string_object; } return 0; }

Después de la compilación, lo ejecuto así: ./bin 0>&1 Lo que esperaba que sucediera es que el "texto" que se envía a stdout, ahora también se convertirá en stdin para el programa y se repetirá para siempre. ¿Por qué no sucede?

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Primero, debe generar líneas nuevas al imprimir en std::cout , de lo contrario, std::getline() no tendrá ninguna línea completa para leer.

Versión mejorada:

 #include <iostream> #include <string> int main() { std::cout << "stars" << std::endl; for(;;) { std::string string_object; std::getline(std::cin, string_object); std::cout << string_object << std::endl; } return 0; }

Ahora prueba esto:

 ./bin >file <file

no ve ninguna salida, porque va al archivo. Pero si detienes el programa y miras el archivo, mira, está lleno de

 stars stars stars stars

:-)

Además, la razón por la que el ciclo de retroalimentación no puede comenzar cuando intenta

 ./bin 0>&1

es que terminas con stdin y stdout conectados a /dev/tty (lo que significa que puedes ver la salida).

Pero un dispositivo TTY nunca puede cerrar el ciclo, porque en realidad consta de dos canales separados, uno que pasa la salida a la terminal y otro que pasa la entrada de la terminal al proceso.

Si usa un archivo regular para entrada y salida, el bucle se puede cerrar. Cada byte escrito en el archivo también se leerá, si el stdin del proceso está conectado a él. Eso es siempre que ningún otro proceso lea el archivo simultáneamente, porque cada byte en una secuencia solo se puede leer una vez.

over 4 years ago · Santiago Trujillo Relatório

0

Porque stdout y stdin no crean un bucle. Pueden apuntar al mismo tty, pero un tty en realidad son dos canales separados, uno para entrada y otro para salida, y no se enlazan entre sí.

Puede intentar crear un bucle ejecutando su programa con su stdin conectado al extremo de lectura de una tubería y con su stdout al extremo de escritura. Eso funcionará con cat :

 mkfifo fifo { echo text; strace cat; } <>fifo >fifo ... read(0, "text\n", 131072) = 5 write(1, "text\n", 5) = 5 read(0, "text\n", 131072) = 5 write(1, "text\n", 5) = 5 ...

Pero no con su programa . Eso es porque su programa está tratando de leer líneas , pero sus escrituras no terminan con una nueva línea. Arreglando eso y también imprimiendo la línea de lectura en stderr (para que no tengamos que usar strace para demostrar que sucede algo en su programa), obtenemos:

 #include <iostream> #include <string> int main() { std::cout << "text" << std::endl; for(;;) { std::string string_object{}; std::getline(std::cin, string_object); std::cerr << string_object << std::endl; std::cout << string_object << std::endl; } }
 g++ foo.cc -o foo mkfifo fifo; ./foo <>fifo >fifo text text text ...

Nota: la forma <>fifo de abrir una canalización con nombre (fifo) se usó para abrir tanto el extremo de lectura como el de escritura a la vez y así evitar el bloqueo. En lugar de reabrir la fifo desde su ruta, la salida estándar podría simplemente duplicarse desde la entrada estándar ( prog <>fifo >&0 ) o la fifo podría abrirse primero como un descriptor de archivo diferente, y luego podrían abrirse la entrada estándar y la salida estándar sin bloqueo, el primero en modo de solo lectura y el segundo en modo de solo escritura ( prog 3<>fifo <fifo >fifo 3>&- ).

Todos funcionarán igual con el ejemplo en cuestión. En Linux, :|prog >/dev/fd/0 (y echo text | strace cat >/dev/fd/0 ) también funcionaría, sin tener que crear una canalización con nombre con mkfifo .

over 4 years ago · Santiago Trujillo Relatório

0

Como está usando gcc, supondré que tiene una pipe disponible.

 #include <cstring> #include <iostream> #include <unistd.h> int main() { char buffer[1024]; std::strcpy(buffer, "test"); int fd[2]; ::pipe(fd); ::dup2(fd[1], STDOUT_FILENO); ::close(fd[1]); ::dup2(fd[0], STDIN_FILENO); ::close(fd[0]); ::write(STDOUT_FILENO, buffer, 4); while(true) { auto const read_bytes = ::read(STDIN_FILENO, buffer, 1024); ::write(STDOUT_FILENO, buffer, read_bytes); #if 0 std::cerr.write(buffer, read_bytes); std::cerr << "\n\tGot " << read_bytes << " bytes" << std::endl; #endif sleep(2); } return 0; }

La sección #if 0 se puede habilitar para obtener la depuración. No pude hacer que funcionara con std::cout y std::cin directamente, pero alguien que sepa más sobre el código de flujo de bajo nivel probablemente podría modificar esto.

Salida de depuración:

 $ ./io_loop test Got 4 bytes test Got 4 bytes test Got 4 bytes test Got 4 bytes ^C
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda