【问题标题】:Open an ofstream with tilde (~) in path name [duplicate]在路径名中使用波浪号 (~) 打开一个 ofstream [重复]
【发布时间】:2019-09-09 10:49:32
【问题描述】:

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

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

【问题讨论】:

标签: c++ linux ofstream


【解决方案1】:

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

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

~ : $HOME 的值

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      在 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访问。

      【讨论】:

        猜你喜欢
        • 2011-03-05
        • 2017-02-28
        • 2011-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-30
        • 2010-12-13
        • 2019-04-30
        相关资源
        最近更新 更多