打开路径名中带有波浪号 (~) 的 ofstream

Open an ofstream with tilde (~) in path name

我必须打开一些文件进行写入,它的名称包含波浪号 (~)。以下代码无法创建所需的文本文件。如果我用 /home/oren 替换 ~ 那么一切正常。

#include <fstream>
#include <string>

const std::string dirname  = "/home/oren/GIT/";
// const std::string dirname  = "~/GIT/";
const std::string filename = "someTextFile";

int main(int argc, char **argv)
{
    std::ofstream log_file(dirname+filename+".txt");
    log_file << "lorem ipsum";
    log_file.close();
}

有什么方法可以(轻松地)处理名称中带有 ~ 的文件吗?

波浪号是 shell 扩展的一部分,它不是由底层操作系统处理的。你需要自己解决。

一个简单的方法是用环境变量HOME(如果存在)的内容替换leading"~/"

路径中的 ~ 快捷方式在文件系统级别并不是什么神奇的东西,打开 ~/GIT 字面上会尝试访问 ~/GIT,即:一个名为 GIT 的文件~ 目录。您可以先创建 ~GIT 来验证这一点。

在命令行中,~ 通常由您的 shell 解析。例如:在 bash:

~ : The value of $HOME

https://www.gnu.org/software/bash/manual/html_node/Tilde-Expansion.html

因此,要达到同样的效果,需要查询$HOME环境变量,将路径中前导~/的用法替换为:

#include <stdlib.h>
const char* home = getenv("HOME")
if (home) { /* replace ~/ with home */ }

此外,在linux上,wordexp函数可用于执行这些替换(~到当前用户,~other_user到其他用户的家)

shell 将波浪号扩展到主目录。 iostream 不使用 shell,因此您必须为它们处理扩展。波浪号实际上是一个在文件名中使用的有效字符,因此无需扩展,文件将创建到名为 ~ 的目录中 - 如果该目录不存在,则失败。

在 C++ 中没有用于 shell 扩展的标准方法,也没有获取主目录的方法,但是在 POSIX 系统中有几种方法:

wordexp 可能是这种情况下最有用的函数之一。您可以将路径传递给函数,它会扩展波浪号、变量和大括号。一个例子:

std::string full = dirname+filename+".txt"
wordexp_t p;
wordexp(full.c_str(), &p, 0);
std::string expanded = p.we_wordv[p.we_offs];
wordfree(&p);
std::ofstream log_file(expanded);

其他选择:

getpwuid 为您提供了一个以主目录作为成员的结构。这也可用于获取另一个用户的主目录,以备不时之需。

HOME 环境变量也应该可用。可以通过标准 std::getenv.

访问