Как мне получить вывод warn () в строку?

Я использую нестандартную функцию warn() (предоставляется BSD) для вывода сообщения об ошибке, если файл не может быть открыт, например:

std::string path = get_path() ;
std::ifstream file(path) ;
if (file.is_open()) { /* do something */ }
else {
warn("%s", path.c_str()) ;
// uses errno to figure out what the error was and outputs it nicely along with the filename
}

Это все очень хорошо для его вывода, но что если я захочу использовать всю строку где-то еще, помимо ее печати? warn() функции, похоже, не имеют формы, которая записывает ошибку в строку. Я попытался свернуть свое собственное, но это кажется очень громоздким по сравнению (кроме того, что я не получил название программы):

this->foo((boost::format("%s: %s") % path % strerror(errno)).str()) ;

Так как я могу получить warn()выводится как строка?

1

Решение

warn выводит свой вывод на стандартный вывод ошибок. Таким образом, вам придется создать механизм для перенаправления стандартного вывода ошибок в место, которое вы можете прочитать обратно в строку. Самый простой способ — перенаправить стандартную ошибку в файл, а затем прочитать файл обратно в виде строки. Вы можете, например, попробовать использовать dup2() чтобы сделать это (как объяснено в ответе на этот вопрос).

Тем не менее, упаковка вашей собственной версии warn вероятно, лучший выбор. Вы можете рассмотреть C vsnprintf() Функция для его реализации, хотя. Есть ответы на этот вопрос этот адрес как с помощью boost::format а также vsnprintf(),

1

Другие решения

Вы правы — нет sprintf аналог (т.е. не гипотетический swarn функция).

Ваш подход кажется жизнеспособным.

0

Похоже, что ваши вращения приводят к результату, похожему на:

path + ": " +  strerror(errno);

По-видимому, название программы, которое она включает, вероятно, просто argv[0]Таким образом, вы могли бы получить примерно эквивалент вашего warn это просто возвращает std::string с чем-то в этом общем порядке:

std::string warn_s(std::string const &path) {
char *pname = strrchr(argv[0], '/');
if (pname == NULL)
pname = argv[0];
return path + pname + ":  " + strerror(errno);
}

Основная трудность здесь заключается в том, что argv является локальным для mainпоэтому вам, вероятно, потребуется либо сохранить его в доступном месте в main, либо использовать какой-то нестандартный механизм для повторного получения этих данных в вашей функции.

К сожалению, документация для warn Я был в состоянии найти достаточно плохо, что, возможно, потребуется немного тестирования / проб и ошибок, если вы хотите точно продублировать вывод.

0
А ты уже прошел курс программирования? Супер скидка!
Прокачать скилл $$$
×