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

C++ 打开路径名中带有波浪号(~)的流,c++,linux,ofstream,C++,Linux,Ofstream,我必须打开一些文件进行写入,文件名包含波浪符号(~)。以下代码无法创建所需的文本文件。如果我将~替换为/home/oren,则一切正常 #include <fstream> #include <string> const std::string dirname = "/home/oren/GIT/"; // const std::string dirname = "~/GIT/"; const std::string filename = "someTextFile

我必须打开一些文件进行写入,文件名包含波浪符号(
~
)。以下代码无法创建所需的文本文件。如果我将
~
替换为
/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();
}
#包括
#包括
常量std::string dirname=“/home/oren/GIT/”;
//常量std::string dirname=“~/GIT/”;
const std::string filename=“someTextFile”;
int main(int argc,字符**argv)
{
std::流日志文件(dirname+filename+“.txt”);
日志文件tilde是shell扩展的一部分,它不是由底层操作系统处理的。您需要自己解决它


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

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

~:价值$HOME

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

#include <stdlib.h>
const char* home = getenv("HOME")
if (home) { /* replace ~/ with home */ }
#包括
const char*home=getenv(“home”)
if(home){/*替换~/为home*/}

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

tilde由shell扩展到主目录。iostreams不使用shell,因此您必须注意它们的扩展。tilde实际上是文件名中使用的有效字符,因此无需扩展,就会将文件创建到名为
~
的目录中,如果目录不存在,则会失败

在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

访问,作为我写此评论时存在的两个答案的补充:取决于路径的来源(用户输入?),程序可能会注意到tilde扩展的其他变体,如
~user
引用给定
用户的主目录。的可能副本等。