root_name() 仅在 Windows 上返回驱动器盘符如"C:",Linux/macOS 返回空字符串;它不处理相对路径,UNC路径返回"\servershare",提取驱动器字母需检查长度≥2且第二字符为':'。

root_name() 在 Windows 上才返回驱动器盘符
std::filesystem::path::root_name() 返回的是路径的“根名”部分,在不同系统语义完全不同。Windows 路径如 C:ooar 的 root_name() 是 "C:";而 Linux/macOS 路径如 /home/user 的 root_name() 是空字符串(""),因为 POSIX 没有“驱动器名”的概念。
这意味着:直接调用 root_name() 并假设它总能拿到盘符,会在非 Windows 平台静默失败。
- 只在
_WIN32宏定义时才应依赖root_name()提取驱动器 - 即使在 Windows,相对路径(如
"data/file.txt")的root_name()也是空的 —— 它不自动补全当前驱动器 - 若路径含 UNC 前缀(如
\serversharepath),root_name()返回"\\server\share",不是单个字母盘符
提取纯驱动器字母(如 "C")要手动剥离冒号和斜杠
root_name() 返回的是 std::filesystem::path 对象,其字符串形式在 Windows 下通常是 "C:" 或 "C:/"(取决于构造方式),不能直接当 C 字符串用。需显式转换并处理边界:
// 示例:安全提取驱动器字母(仅限 Windows)
#ifdef _WIN32
std::filesystem::path p = "C:\temp\log.txt";
auto root = p.root_name().string(); // 可能是 "C:" 或 "C:/"
if (!root.empty() && root.length() >= 2 && root[1] == ':') {
char drive_letter = root[0];
// drive_letter 现在是 'C'
}
#endif
- 必须检查长度 ≥ 2 且第二个字符是
':',否则可能误判 UNC 或空路径 - 不要用
substr(0,1)后再c_str()——std::string临时对象生命周期可能早于使用点 - 避免直接对
root_name().c_str()取址:返回的是临时path的内部缓冲区,极易悬垂
跨平台代码里别硬依赖 root_name() 获取驱动器信息
如果业务逻辑真需要“当前工作目录所在驱动器”(比如日志写入同盘符的固定位置),root_name() 不够用 —— 它不处理相对路径,也不反映当前驱动器上下文。
立即学习“C++免费学习笔记(深入)”;
- Windows 下更可靠的方式是调用
GetFullPathNameA/W或_getdcwd()获取绝对路径后再解析 - 想获取当前驱动器(如 CMD 中的
C:),应调用_getdrive()(返回 1-based 数字)配合'A' + drive_num - 1 - 跨平台库如 Boost.Filesystem 也遵循同样规则:
root_name()行为与标准一致,不额外封装驱动器逻辑
常见错误:把 root_name() 和 root_path() / root_directory() 混用
这三个成员函数返回完全不同的东西,但名字太像,容易写错:
-
root_name()→ 驱动器或 UNC 主机共享(Windows:"C:";Linux:"") -
root_directory()→ 根目录分隔符(Windows/Linux 都是"\"或"/") -
root_path()→root_name() + root_directory()(Windows:"C:\";Linux:"/")
例如路径 "C:foo.txt"(无反斜杠):它的 root_name() 是 "C:",但 root_directory() 是空的 —— 因为没出现 '\'。这种“相对路径挂载在驱动器上”的格式会让新手误以为 root_path() 存在。
真正稳定的驱动器提取,永远要结合平台判断、路径规范化和显式字符检查。靠一个 root_name() 调用就想通吃所有 Windows 路径变体,基本会掉进 UNC、网络驱动器、当前目录隐式绑定这些坑里。



















