Я использую нестандартную функцию 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()
выводится как строка?
warn
выводит свой вывод на стандартный вывод ошибок. Таким образом, вам придется создать механизм для перенаправления стандартного вывода ошибок в место, которое вы можете прочитать обратно в строку. Самый простой способ — перенаправить стандартную ошибку в файл, а затем прочитать файл обратно в виде строки. Вы можете, например, попробовать использовать dup2()
чтобы сделать это (как объяснено в ответе на этот вопрос).
Тем не менее, упаковка вашей собственной версии warn
вероятно, лучший выбор. Вы можете рассмотреть C vsnprintf()
Функция для его реализации, хотя. Есть ответы на этот вопрос этот адрес как с помощью boost::format
а также vsnprintf()
,
Вы правы — нет sprintf
аналог (т.е. не гипотетический swarn
функция).
Ваш подход кажется жизнеспособным.
Похоже, что ваши вращения приводят к результату, похожему на:
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
Я был в состоянии найти достаточно плохо, что, возможно, потребуется немного тестирования / проб и ошибок, если вы хотите точно продублировать вывод.