用C 的名称重命名文件
Renaming a file with an en dash in the name in C++
在我正在从事的项目中,我使用文件,我在继续之前检查它们是否存在。重命名,甚至可以使用文件路径中的" en Dash"的文件似乎不可能。
std::string _old = "D:\Folder\This – by ABC.txt";
std::rename(_old.c_str(), "New.txt");
在这里,_old变量被解释为d: folder this -abc.txt我尝试了
setlocale(LC_ALL, "");
//and
setlocale(LC_ALL, "C");
//or
setlocale(LC_ALL, "en_US.UTF-8");
但是它们都没有起作用。.
这取决于操作系统。在Linux文件名中是简单的字节数组:忘记编码,只重命名文件。
,但看来您正在使用Windows,而文件名实际上是一个包含16位字符的null终止字符串。在这种情况下,最好的方法是使用wstring
而不是用编码混乱。
不要尝试编写独立的代码来解决平台特定问题。Windows使用Unicode进行文件名,因此您必须编写特定于平台的代码,而不是使用标准函数rename
。
只需写L"D:\Folder\This u2013 by ABC.txt"
并调用_wrename
。
Windows ANSI Western编码具有Unicode N-Dash,U 2013,;,作为代码点150(十进制)。当您将其输出使用Active Code Page 437(原始IBM PC字符集)或兼容的控制台时,则将其解释为An“ rdquo;。因此,您的字符串文字中有正确的CodePage 1252字符,要么是因为
-
您正在使用Visual C ,默认为Windows ANSI编码编码狭窄的字符串文字,或
-
您正在使用旧版本的G ,该版本不进行标准规定的转换和检查,但只能通过其机械直接传递狭窄的字符字节,并且您的源代码被编码为Windows ANSI Western(或兼容)或
-
我没想到的东西。
对于前两个可能性中的任何一个
';      rename
调用将有效。
我测试了它确实与Visual C 一起使用。我周围没有G 的旧版本,但是我测试了它与版本5.1一起工作。也就是说,我测试了该文件确实将其重命名为New.txt
。
// Source encoding: UTF-8
// Execution character set: Windows ANSI Western a.k.a. codepage 1252.
#include <stdio.h> // rename
#include <stdlib.h> // EXIT_SUCCESS, EXIT_FAILURE
#include <string> // std::string
using namespace std;
auto main()
-> int
{
string const a = ".\This – by ABC.txt"; // Literal encoded as CP 1252.
return rename( a.c_str(), "New.txt" ) == 0? EXIT_SUCCESS : EXIT_FAILURE;
}
示例:
[c: my forums so 265]&gt; dir/b *.txt 文件未找到[c: my forums so 265]&gt; g r.cpp -fexec -charset = cp1252 [c: my forums so 265]&gt; type nul&gt;" this - by abc.txt" [c: my forums so 265]&gt;运行退出代码0[c: my forums so 265]&gt; dir/b *.txt new.txt[c: my forums so 265]&gt;_
&hellip;其中run
只是报告退出代码的批处理文件。
如果您的Windows ANSI CodePage不是CodePage 1252,则需要使用特定的Windows ANSI CodePage。
您可以通过GetACP
API函数检查Windows ANSI CodePage,或者通过此命令:
[c: my forums so 265]&gt; WMIC OS获取代码集/值|查找" =" 代码= 1252[c: my forums so 265]&gt;_
如果该代码epage支持n-dash字符,则代码将起作用。
此编码模型基于每个相关主要语言环境(包括字符编码)的一个版本。
一种替代方法是在Unicode中完成所有操作。这可以通过Boost文件系统进行便捷完成,该系统将在C 17中的标准库中采用。或者,您可以使用Windows API或Windows中标准库的标准扩展名,即_rename
。
使用Visual C 2015的实验文件系统模块的示例:
// Source encoding: UTF-8
// Execution character set: irrelevant (everything's done in Unicode).
#include <stdlib.h> // EXIT_SUCCESS, EXIT_FAILURE
#include <filesystem> // In C++17 and later, or Visual C++ 2015 and later.
using namespace std::tr2::sys;
auto main()
-> int
{
path const old_path = L".\This – by ABC.txt"; // Literal encoded as wide string.
path const new_path = L"New.txt";
try
{
rename( old_path, new_path );
return EXIT_SUCCESS;
}
catch( ... )
{}
return EXIT_FAILURE;
}
要适当地对可移植代码执行此操作,您可以使用Boost,也可以创建一个使用任何可用实现的包装标头。
它确实取决于平台,unicode是头痛。取决于您使用的编译器。对于来自MS(VS2010或以上的VS2010)的较旧元素,您需要使用MSDN中描述的API。此测试示例可以使用您的名称创建文件,然后将其重命名
// #define _UNICODE // might be defined in project
#include <string>
#include <tchar.h>
#include <windows.h>
using namespace std;
// Convert a wide Unicode string to an UTF8 string
std::string utf8_encode(const std::wstring &wstr)
{
if( wstr.empty() ) return std::string();
int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
std::string strTo( size_needed, 0 );
WideCharToMultiByte (CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
return strTo;
}
// Convert an UTF8 string to a wide Unicode String
std::wstring utf8_decode(const std::string &str)
{
if( str.empty() ) return std::wstring();
int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
std::wstring wstrTo( size_needed, 0 );
MultiByteToWideChar (CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
return wstrTo;
}
int _tmain(int argc, _TCHAR* argv[] ) {
std::string pFileName = "C:\This xe2x80x93 by ABC.txt";
std::wstring pwsFileName = utf8_decode(pFileName);
// can use CreateFile id instead
HANDLE hf = CreateFileW( pwsFileName.c_str() ,
GENERIC_READ | GENERIC_WRITE,
0,
0,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
0);
CloseHandle(hf);
MoveFileW(utf8_decode("C:\This xe2x80x93 by ABC.txt").c_str(), utf8_decode("C:\This xe2x80x93 by ABC 2.txt").c_str());
}
这些帮助者仍然存在问题,因此您可以将一个终止的字符串终止。
std::string utf8_encode(const std::wstring &wstr)
{
std::string strTo;
char *szTo = new char[wstr.length() + 1];
szTo[wstr.size()] = ' ';
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, szTo, (int)wstr.length(), NULL, NULL);
strTo = szTo;
delete[] szTo;
return strTo;
}
// Convert an UTF8 string to a wide Unicode String
std::wstring utf8_decode(const std::string &str)
{
std::wstring wstrTo;
wchar_t *wszTo = new wchar_t[str.length() + 1];
wszTo[str.size()] = L' ';
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, wszTo, (int)str.length());
wstrTo = wszTo;
delete[] wszTo;
return wstrTo;
}
一个具有转换字符大小的问题。.致电0,以0,因为目标缓冲区的大小允许获得转换所需的字符大小。然后,它将返回目标缓冲区大小所需的字节数。所有这些与代码的杂耍都解释了为什么像QT这样的框架变得如此复杂的代码以支持基于Unicode的文件系统。实际上,摆脱所有可能的错误的最佳成本效益方法是使用这种框架。
vs2015
std::string _old = u8"D:\Folder\This xe2x80x93 by ABC.txt"s;
根据他们的文档。我无法检查一个。
mingw。
std::string _old = u8"D:\Folder\This xe2x80x93 by ABC.txt";
std::cout << _old.data();
输出包含正确的文件名...但是对于文件API,您仍然需要做正确的转换
- 如何在Visual Studio Code中重命名我的a.exe文件?
- 将内容从第一个文件("constituencies")移动到第二个文件("temp")并在之后重命名时,我的文件被删除
- 以编程方式防止重命名或删除文件,但仍使其可写
- 使用 stdio.h 重新定位和重命名文件C++
- 如何检测哪些进程更改,重命名或创建文件?
- 录制后无法重命名 rosbag 文件
- 将文件重命名为已存在的文件名
- 移动了 QT 项目,重命名文件夹和项目名称,Moc'ing 返回"'-I'之后缺少值"
- 将 .c 文件重命名为 .cpp,导入 Cython 库失败
- 为什么将可执行文件重命名为临时文件的此代码段不能按预期工作?
- 如何在 C++ 中将文件从 ext4 文件系统重命名为 ntfs 文件系统
- 用C 的名称重命名文件
- 如何在C++中重命名文件
- directory_iterator file_iter重命名文件夹中的文件
- 如何使用rename()函数(c++)用字符串重命名文件
- 重命名文件夹内的文件- Unicode等效函数
- 如何使用wstring重命名文件
- 在Windows 8上用C++重命名文件
- 如何在Windows上按句柄重命名文件
- 使用readdirectorychangesc++重命名文件夹后获取旧名称和新名称