rename是C标准库函数,非C++标准,需包含,路径用C字符串,不跨文件系统,不覆盖目标;C++17推荐用std::filesystem::rename。

rename 函数在 C++ 中直接可用,但行为依赖底层系统
rename 不是 C++ 标准库函数,而是来自 C 标准库 (或 C 头文件 ),C++ 程序中可直接调用。它的签名是:int rename(const char* oldname, const char* newname);。返回 0 表示成功,非 0 表示失败(具体错误码需查 errno)。
注意:它不支持跨文件系统移动,也不能覆盖已存在的目标文件(在 Windows 上可能允许,Linux/macOS 默认不允许)。
- 路径必须是 C 风格字符串(
const char*),不能直接传std::string,需用.c_str() - 如果
newname已存在,多数 POSIX 系统会失败并置errno = EEXIST;Windows 的rename可能静默覆盖(行为不一致,不可依赖) - 源和目标必须在同一个挂载点(同磁盘分区),否则返回 -1 且
errno = EXDEV
跨平台安全重命名要先检查目标是否存在
因为 rename 对已存在目标的处理不统一,生产代码中应显式判断并决定是否覆盖:
#include#include #include // for stat on POSIX #include // for _access on Windows bool safe_rename(const std::string& oldpath, const std::string& newpath, bool overwrite = false) { // 先检查目标是否存在
ifdef _WIN32
if (_access(newpath.c_str(), 0) == 0) {else
struct stat st; if (stat(newpath.c_str(), &st) == 0) {endif
if (!overwrite) return false; // 尝试删除已有文件(仅当有权限时) if (std::remove(newpath.c_str()) != 0) return false; } return std::rename(oldpath.c_str(), newpath.c_str()) == 0;}
立即学习“C++免费学习笔记(深入)”;
这段逻辑绕开了
rename的模糊语义,把“覆盖”控制权交还给调用者。更现代的替代方案:C++17
std::filesystem::rename如果你的编译器支持 C++17(如 GCC 8+、Clang 7+、MSVC 2017 Update 5+),强烈推荐用
std::filesystem:
- 接口统一:
std::filesystem::rename(old_p, new_p)抛出std::filesystem::filesystem_error异常,错误信息更明确- 自动处理路径分隔符(
/或\)和编码细节- 支持跨文件系统移动(本质是 copy + unlink,但对用户透明)
- 可配合
std::filesystem::exists()、std::filesystem::status()做前置判断启用方式:编译时加
-std=c++17(GCC/Clang),MSVC 默认开启;链接时可能需要-lstdc++fs(GCC)或确保 VS 版本足够新。常见错误和调试线索
调用
rename失败时,别只看返回值,务必检查errno:
ENOENT:源路径不存在,或目标父目录不存在(rename("a.txt", "dir/b.txt")中dir/不存在)EACCES:权限不足(源/目标目录不可写,或源文件被其他进程独占打开)EXDEV:源和目标不在同一设备——此时只能用复制+删除组合实现EISDIR/ENOTDIR:路径类型错配(比如把文件重命名为目录名,或反之)Windows 下尤其要注意:如果目标文件正被记事本、资源管理器预览窗格或防病毒软件占用,
rename会失败且errno可能为 13(EACCES)而非更直观的错误码。









