# Capture standard output from write\\1 predicate in C++

**URL:** <https://swi-prolog.discourse.group/t/capture-standard-output-from-write-1-predicate-in-c/8523>\
**Category:** Algorithm\
**Created:** [October 8, 2024, 1:05pm UTC](https://swi-prolog.discourse.group/t/capture-standard-output-from-write-1-predicate-in-c/8523 "2024-10-08T13:05:10Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lorenzo](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/lorenzo/32/6320_2.png) [@Lorenzo](https://swi-prolog.discourse.group/u/Lorenzo)\
**Post date:** [October 8, 2024, 1:05pm UTC](https://swi-prolog.discourse.group/t/capture-standard-output-from-write-1-predicate-in-c/8523/1 "2024-10-08T13:05:10Z")

</div>

Hey, it’s me again. I’m currently looking for a way to capture an output from a write\1, so I can manipulate the string as I want.  
Here is the example:

```prolog
PlCall("assert", PlTermv(PlCompound("myprint :- write('soy un poco loco')")));
PlCall("myprint");

```

With this code I get the standard output in my cmd with the string:

```prolog
soy un poco loco

```

But I want, for example, put it in a string and manipulate it without using standard output redirection if possible

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [October 8, 2024, 1:30pm UTC](https://swi-prolog.discourse.group/t/capture-standard-output-from-write-1-predicate-in-c/8523/2 "2024-10-08T13:30:48Z")

</div>

I guess the simplest is to call with\_output\_to/2, as in

```
 with_output_to(string(S), Goal).

```

To make it simpler, define in your Prolog file e.g.,

```prolog
:- meta_predicate capture_in_string(-,0).
capture_in_string(S, Goal) :- with_output_to(string(S), Goal).

```

This should capture all output written to `current_output`

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [October 8, 2024, 2:48pm UTC](https://swi-prolog.discourse.group/t/capture-standard-output-from-write-1-predicate-in-c/8523/3 "2024-10-08T14:48:53Z")

</div>

The generic C++ interface to streams is `PlStream`, but it’s a fairly thin wrapper on the C API.

If you want a stream for writing to memory, see `Sopenmem()` – there’s an example of its use in `packages/odbc/ofbc.c`. You can convert the `IOSTREAM*` to a `PlStream`. See also `PlAcquireStream`.

(I’ve wanted this a few times, so maybe it’s worthwhile making a nice C++ API for writing to a string.)

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [October 8, 2024, 5:29pm UTC](https://swi-prolog.discourse.group/t/capture-standard-output-from-write-1-predicate-in-c/8523/4 "2024-10-08T17:29:03Z")

</div>

> [@peter.ludemann](#):
>
> (I’ve wanted this a few times, so maybe it’s worthwhile making a nice C++ API for writing to a string.)

I’m not sure. There may be exceptions, but in general you do not want to exchange text when combining Prolog with some other language.

Playing around with the standard streams is rather tricky, so possibly using with\_output\_to/2 is a good idea anyway … You already have to call Prolog anyway. The main reason to do it from C++ might be if there is a huge amount of output to be captured, i.e., more than what fits on the Prolog stack.

---

<div class="post-metadata">

**Author:** ![Lorenzo](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/lorenzo/32/6320_2.png) [@Lorenzo](https://swi-prolog.discourse.group/u/Lorenzo)\
**Post date:** [October 9, 2024, 7:22am UTC](https://swi-prolog.discourse.group/t/capture-standard-output-from-write-1-predicate-in-c/8523/5 "2024-10-09T07:22:34Z")

</div>

> [@jan](#):
>
> ```prolog
> :- meta_predicate capture_in_string(-,0).
> capture_in_string(S, Goal) :- with_output_to(string(S), Goal).
> 
> ```

This helped me out a lot, I added this to the bottom of the knowledge base and, after that, I added this code to my C++ testing project

```prolog
openPrologFile("planTest");
PlTermv theTest(2);
theTest[1].unify_atom("test");
PlQuery theQuery("capture_in_string", theTest);
try {
    PlCheckFail(theQuery.next_solution());
    cout << "solution:\n" << theTest[0].as_string() << "\n";
}
catch (PlFail f) {
    cerr << "err\n";
}

```

And it worked!  
Don’t pay attention to openPrologFile, it’s just a quick procedure I added to quickly prompt `PlCall("consult",...)` with exception handling.
