Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

297
Vistas
How to redirect program output as its input

I've written a simple C++ program for tutorial purposes. My goal is to loop it infinitely.

#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;
}

After compilation I run it like this: ./bin 0>&1 What I expected to happen is that the "text" that is output to stdout, and it will now become also stdin for the program and it will loop forever. Why doesn't it happen?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

First, you need to output newlines when printing to std::cout, otherwise std::getline() won't have any complete line to read.

Improved version:

#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;
}

Now try this:

./bin >file <file

you don't see any output, because it's going to the file. But if you stop the program and look at the file, behold, it's full of

stars
stars
stars
stars

:-)

Also, the reason that the feedback loop cannot start when you try

./bin 0>&1

is, that you end up with both stdin and stdout connected to /dev/tty (meaning that you can see the output).

But a TTY device cannot ever close the loop, because it actually consists of two separate channels, one passing the output to the terminal, one passing the terminal input to the process.

If you use a regular file for in- and output, the loop can be closed. Every byte written to the file will be read from it as well, if the stdin of the process is connected to it. That's as long as no other process reads from the file simultaneously, because each byte in a stream can be only read once.

over 4 years ago · Santiago Trujillo Denunciar

0

Because the stdout and stdin don't create a loop. They may point to the same tty, but a tty is actually two separate channels, one for input and one for output, and they don't loop back into one another.

You can try creating a loop by running your program with its stdin connected to the read end of a pipe, and with its stdout to its write end. That will work with 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
...

But not with your program. That's because your program is trying to read lines, but its writes are not terminated by a newline. Fixing that and also printing the read line to stderr (so we don't have to use strace to demonstrate that anything happens in your program), we get:

#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
...

Note: the <>fifo way of opening a named pipe (fifo) was used in order to open both its read and its write end at once and so avoid blocking. Instead of reopening the fifo from its path, the stdout could simply be dup'ed from the stdin (prog <>fifo >&0) or the fifo could be first opened as a different file descriptor, and then the stdin and stdout could be opened without blocking, the first in read-only mode and the second in write-only mode (prog 3<>fifo <fifo >fifo 3>&-).

They will all work the same with the example at hand. On Linux, :|prog >/dev/fd/0 (and echo text | strace cat >/dev/fd/0) would also work -- without having to create a named pipe with mkfifo.

over 4 years ago · Santiago Trujillo Denunciar

0

Since you're using gcc, I'm going to assume you have pipe available.

#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;
}

The #if 0 section can be enabled to get debugging. I couldn't get it to work with std::cout and std::cin directly, but somebody who knows more about the low-level stream code could probably tweak this.

Debug output:

$ ./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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda