Установка внутреннего буфера, используемого стандартным потоком (pubsetbuf)

Для сохранения исходных stdout и stderr вы можете использовать:

exec [fd number]<&1 
exec [fd number]<&2

Например, следующий код будет печатать «walla1» и «walla2» в файле журнала (a.txt), walla3 "в stdout," walla4 "в stderr.

#!/bin/bash

exec 5<&1
exec 6<&2

exec 1> ~/a.txt 2>&1

echo "walla1"
echo "walla2" >&2
echo "walla3" >&5
echo "walla4" >&6
24
задан Deduplicator 27 December 2015 в 22:15
поделиться

3 ответа

После некоторых дополнительных исследований по этой проблеме, и Внимательно изучив свой код, я наткнулся на сообщение , в котором предлагалось использовать ручной код std :: streambuf . Идея этого кода заключается в создании streambuf , который инициализирует свои внутренние компоненты для обращения к данному буферу. Код выглядит следующим образом:

#include <streambuf>

template <typename char_type>
struct ostreambuf : public std::basic_streambuf<char_type, std::char_traits<char_type> >
{
    ostreambuf(char_type* buffer, std::streamsize bufferLength)
    {
        // set the "put" pointer the start of the buffer and record it's length.
        setp(buffer, buffer + bufferLength);
    }
};

Теперь, если вы посмотрите мой исходный код , вы заметите, что мне действительно не нужен был поток строк для начала. Все, что мне действительно нужно, - это способ записи во внешний буфер с использованием библиотеки IOStream , а std :: ostream - гораздо лучший тип для решения этой проблемы. Кстати, Я подозреваю, что именно так реализован тип array_sink из Boost.IOStreams .

Вот модифицированный код, который использует мой тип ostreambuf .

#include <ostream>
#include "ostreambuf.h"  // file including ostreambuf struct from above.

void FillBuffer(char* buffer, unsigned int size)
{
    ostreambuf<char> ostreamBuffer(buffer, size);
    std::ostream messageStream(&ostreamBuffer);

    messageStream << "Hello" << std::endl;
    messageStream << "World!" << std::endl;
}
19
ответ дан 29 November 2019 в 00:15
поделиться

Похоже, это задание для (официально устаревшего, но все еще стандартного) std :: strstream . Вы также можете посмотреть библиотеку Boost.IOStreams , в частности array_sink .

4
ответ дан 29 November 2019 в 00:15
поделиться

Как говорится в опубликованной вами ссылке: «определенные реализации могут change ".

Не могли бы вы просто вернуть объект std :: string, а затем использовать std :: string :: c_str () или std :: string :: data () в том месте, где требуется буфер символов?

В качестве альтернативы используйте sprintf () из библиотеки C, тогда вся операция может быть завершена в переданном буфере. Поскольку такой способ может привести к потенциальному переполнению буфера и вы используете Visual C ++, вы можете рассмотреть sprintf_s

1
ответ дан 29 November 2019 в 00:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: