How to Capture Stdout to a String

How can I capture STDOUT to a string?

Redirect Standard Output to a StringIO Object

You can certainly redirect standard output to a variable. For example:

# Set up standard output as a StringIO object.
foo = StringIO.new
$stdout = foo

# Send some text to $stdout.
puts 'hi'
puts 'bye'

# Access the data written to standard output.
$stdout.string
# => "hi\nbye\n"

# Send your captured output to the original output stream.
STDOUT.puts $stdout.string

In practice, this is probably not a great idea, but at least now you know it's possible.

redirect output from stdout to a string?

char string[SIZE];
freopen("/dev/null", "a", stdout);
setbuf(stdout, string);

see freopen and setbuf for their definitions

In Go, how do I capture stdout of a function into a string?

I agree you should use the fmt.Fprint functions if you can manage it. However, if you don't control the code whose output you're capturing, you may not have that option.

Mostafa's answer works, but if you want to do it without a temporary file you can use os.Pipe. Here's an example that's equivalent to Mostafa's with some code inspired by Go's testing package.

package main

import (
"bytes"
"fmt"
"io"
"os"
)

func print() {
fmt.Println("output")
}

func main() {
old := os.Stdout // keep backup of the real stdout
r, w, _ := os.Pipe()
os.Stdout = w

print()

outC := make(chan string)
// copy the output in a separate goroutine so printing can't block indefinitely
go func() {
var buf bytes.Buffer
io.Copy(&buf, r)
outC <- buf.String()
}()

// back to normal state
w.Close()
os.Stdout = old // restoring the real stdout
out := <-outC

// reading our temp stdout
fmt.Println("previous output:")
fmt.Print(out)
}

Can I redirect the stdout into some sort of string buffer?

from cStringIO import StringIO # Python3 use: from io import StringIO
import sys

old_stdout = sys.stdout
sys.stdout = mystdout = StringIO()

# blah blah lots of code ...

sys.stdout = old_stdout

# examine mystdout.getvalue()

How to get output sent to stdout onto a string

Use rdbuf.

std::stringstream stream;
auto * old = std::cout.rdbuf(stream.rdbuf());
CallFunction();
std::cout.rdbuf(old);
std::string value = stream.str();

redirect stdout/stderr to a string

Yes, you can redirect it to an std::stringstream:

std::stringstream buffer;
std::streambuf * old = std::cout.rdbuf(buffer.rdbuf());

std::cout << "Bla" << std::endl;

std::string text = buffer.str(); // text will now contain "Bla\n"

You can use a simple guard class to make sure the buffer is always reset:

struct cout_redirect {
cout_redirect( std::streambuf * new_buffer )
: old( std::cout.rdbuf( new_buffer ) )
{ }

~cout_redirect( ) {
std::cout.rdbuf( old );
}

private:
std::streambuf * old;
};

How to copy os.Stdout output to string variable

Create pipe and set stdout to the pipe writer. Start a goroutine to copy the pipe reader to a buffer. When done, close the pipe writer and wait for goroutine to complete reading. Return the buffer as a string.

// capture replaces os.Stdout with a writer that buffers any data written 
// to os.Stdout. Call the returned function to cleanup and get the data
// as a string.
func capture() func() (string, error) {
r, w, err := os.Pipe()
if err != nil {
panic(err)
}

done := make(chan error, 1)

save := os.Stdout
os.Stdout = w

var buf strings.Builder

go func() {
_, err := io.Copy(&buf, r)
r.Close()
done <- err
}()

return func() (string, error) {
os.Stdout = save
w.Close()
err := <-done
return buf.String(), err
}

}

Use it like this:

done := capture()
fmt.Println("Hello, playground")
capturedOutput, err := done()
if err != nil {
// handle error
}

playground example

How to capture stdout output from a Python function call?

Try this context manager:

from io import StringIO 
import sys

class Capturing(list):
def __enter__(self):
self._stdout = sys.stdout
sys.stdout = self._stringio = StringIO()
return self
def __exit__(self, *args):
self.extend(self._stringio.getvalue().splitlines())
del self._stringio # free up some memory
sys.stdout = self._stdout

Usage:

with Capturing() as output:
do_something(my_object)

output is now a list containing the lines printed by the function call.

Advanced usage:

What may not be obvious is that this can be done more than once and the results concatenated:

with Capturing() as output:
print('hello world')

print('displays on screen')

with Capturing(output) as output: # note the constructor argument
print('hello world2')

print('done')
print('output:', output)

Output:

displays on screen                     
done
output: ['hello world', 'hello world2']

Update: They added redirect_stdout() to contextlib in Python 3.4 (along with redirect_stderr()). So you could use io.StringIO with that to achieve a similar result (though Capturing being a list as well as a context manager is arguably more convenient).



Related Topics



Leave a reply



Submit