Reputation: 81
I want to rename some of the files ,
The names of some of the files are Russian, Chinese, and German
The program can only modify files whose name is English.
What is the problem ? please guide me
std::wstring ToUtf16(std::string str)
{
std::wstring ret;
int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0);
if (len > 0)
{
ret.resize(len);
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &ret[0], len);
}
return ret;
}
int main()
{
const std::filesystem::directory_options options = (
std::filesystem::directory_options::follow_directory_symlink |
std::filesystem::directory_options::skip_permission_denied
);
try
{
for (const auto& dirEntry :
std::filesystem::recursive_directory_iterator("C:\\folder",
std::filesystem::directory_options(options)))
{
filesystem::path myfile(dirEntry.path().u8string());
string uft8path1 = dirEntry.path().u8string();
string uft8path3 = myfile.parent_path().u8string() + "/" + myfile.filename().u8string();
_wrename(
ToUtf16(uft8path1).c_str()
,
ToUtf16(uft8path3).c_str()
);
std::cout << dirEntry.path().u8string() << std::endl;
}
}
catch (std::filesystem::filesystem_error & fse)
{
std::cout << fse.what() << std::endl;
}
system("pause");
}
Upvotes: 0
Views: 278
Reputation: 31599
filesystem::path myfile(dirEntry.path().u8string());
Windows supports UTF16 and ANSI, there is no UTF8 support for APIs (not standard anyway). When you supply UTF8 string, it thinks there is ANSI input. Use wstring()
to indicate UTF16:
filesystem::path myfile(dirEntry.path().wstring());
or just put:
filesystem::path myfile(dirEntry);
Likewise, use wstring()
for other objects.
wstring path1 = dirEntry.path();
wstring path3 = myfile.parent_path().wstring() + L"/" + myfile.filename().wstring();
_wrename(path1.c_str(), path3.c_str());
Renaming the files will work fine when you have UTF16 input. But there is another problem with console's limited Unicode support. You can't print some Asian characters with font changes. Use the debugger or MessageBoxW
to view Asian characters.
Use _setmode
and wcout
to print UTF16.
Also note, std::filesystem
supports /
operator for adding path. Example:
#include <io.h> //for _setmode
#include <fcntl.h>
...
int main()
{
_setmode(_fileno(stdout), _O_U16TEXT);
const std::filesystem::directory_options options = (
std::filesystem::directory_options::follow_directory_symlink |
std::filesystem::directory_options::skip_permission_denied
);
try
{
for(const auto& dirEntry :
std::filesystem::recursive_directory_iterator(L"C:\\folder",
std::filesystem::directory_options(options)))
{
filesystem::path myfile(dirEntry);
auto path1 = dirEntry;
auto path3 = myfile.parent_path() / myfile;
std::wcout << path1 << ", " << path3 << endl;
//filesystem::rename(path1, path3);
}
}
...
}
Upvotes: 1