I am writing a simple function for use in one of my utility implementation files. I recently discovered–while using one of the C++17 libraries–that outputting directory entries using the std::filesystem::path::string() function inside a call to printf() only results in a string of odd characters being sent to STDOUT. Using cout results in no issue. Here is the code:
if( !initialized )
{
try
{
const filesystem::path MODELS_DIRECTORY = R"(C:\-----\-----\-----\models)";
const filesystem::path RESOURCES_DIRECTORY = filesystem::relative(R"(\Resources)", MODELS_DIRECTORY);
for( const filesystem::directory_entry& dir_entry : filesystem::directory_iterator{ MODELS_DIRECTORY } )
{
string test = "this\\is\\a test\\";
string directory = dir_entry.path().string();
printf("%s\n", test);
//cout << directory << endl;
}
}
catch( filesystem::filesystem_error& fs_err )
{
printf( "fs exception caught in GraphicsDataCatalog::InitCatalog()" );
}
initialized = true;
}
Using the testing mechanism composed of std::string test and the call to printf() shows that the double backslashes are culprit. Erasing the space in the string does not solve the issue–I assume perhaps there is a format specifier to resolve the erratic characters printed to the console. Using cout with the string returned by the dir_entry.path().string() call results in success.
Does anyone have more knowledge on the subject?
MRE (Minimally reproducible example):
#include <iostream>
using namespace std;
int main()
{
const string PASS_STRING = "This is a test.";
const string FAIL_STRING = "This\\is not\\a\\test.";
cout << PASS_STRING << endl;
cout << "Test passed.\n" << endl;
printf( "%s\n", FAIL_STRING );
printf( "Test failed.\n" );
return 0;
}
>Solution :
The %s format specifier takes a char *, not a std::string. You’re passing the wrong argument type to printf.