I am trying to write formatted wstring logs to file using fmt. I can do it by using fmt::format(...)
and fmt::vprint
but I want to use fmt::output_file
to do it, however I am getting compile error.
Below code shows two ways that are working and the last one that does not work.
...
#include <fmt/format.h>
#include <fmt/xchar.h>
#include <fmt/os.h>
template <typename... Args>
static void Helper(const std::wstring& str, const Args&... args)
{
std::filesystem::create_directories("C:\\Logs");
std::filesystem::path file_path("C:\\Logs\\dll");
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
auto file_path_utf8 = converter.to_bytes(file_path.wstring());
// Method 1 Working
std::wofstream f_stream(file_path.string().c_str(), std::ios::app);
f_stream << fmt::format(str, args...);
// Method 2 Working
std::FILE* file = std::fopen(file_path.string().c_str(), "a");
fmt::vprint(file, str.c_str(), fmt::make_wformat_args(args...));
std::fclose(file);
// Method 3 NOT WORKING
auto file = fmt::output_file(file_path.string().c_str(), fmt::file::WRONLY | fmt::file::CREATE | fmt::file::APPEND);
file.print(str, args...);
}
With method 3 I am getting the following compilation error.
error C2664: 'void fmt::v9::ostream::print<>(fmt::v9::basic_format_string<char>)': cannot convert argument 1 from 'const std::wstring' to 'fmt::v9::basic_format_string<char>'
The example for this print
member function is given on https://fmt.dev/latest/api.html#system-apis
How do I make file.print
work with const std::wstring
when its expecting fmt::v9::basic_format_string<char>
by default?
fmt::output_file
is an experimental optimized API and as such it intentionally doesn't support wide strings because the latter would require transcoding. If you want to write wide strings you can do it with fmt::print
and standard FILE
or ostream
:
#include <fmt/xchar.h>
#include <filesystem>
template <typename... T>
void helper(const std::wstring& str, T&&... args) {
std::filesystem::path file_path("path/to/logs");
auto file = fopen(file_path.string().c_str(), "w");
fmt::print(file, fmt::runtime(str), std::forward<T>(args)...);
fclose(file); // Better use RAII instead.
}
int main() {
helper(L"{}", 42);
}