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

Open an ofstream with tilde (~) in path name

本文关键字:的流 路径名      更新时间:2023-10-16

我必须打开一些文件进行写入,它的名称包含波浪号(~(。以下代码无法创建所需的文本文件。如果我用/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();
}

有没有办法(轻松(处理名称中带有~的文件?

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

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

~ : $HOME的值

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

因此,要达到相同的效果,您必须查询 envvar$HOME,并替换路径中前导~/的用法:

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

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

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

一种简单的方法是将前导"~/"替换为环境变量HOME的内容(如果存在(。

波浪号由 shell 扩展到主目录。iostreams不使用shell,所以你必须照顾它们的扩展。波浪号实际上是在文件名中使用的有效字符,因此无需扩展,文件将创建到名为~的目录中 - 如果该目录不存在,则会失败。

对于 shell 扩展,C++没有标准的方法,也没有获取主目录的方法,但在 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访问它。