Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么可以';t QFile从~&引用;目录_C++_Qt_Qt4_Tilde Expansion_Qfile - Fatal编程技术网

C++ 为什么可以';t QFile从~&引用;目录

C++ 为什么可以';t QFile从~&引用;目录,c++,qt,qt4,tilde-expansion,qfile,C++,Qt,Qt4,Tilde Expansion,Qfile,我尝试了下面的简短示例,以了解我正在开发的更大程序中的一个bug。QFile似乎不支持主目录的unix(或shell)表示法: #include <QFile> #include <QDebug> int main() { QFile f("~/.vimrc"); if (f.open(QIODevice::ReadOnly)) { qDebug() << f.readAll()

我尝试了下面的简短示例,以了解我正在开发的更大程序中的一个bug。QFile似乎不支持主目录的unix(或shell)表示法:

#include <QFile>
#include <QDebug>

int main()
{
        QFile f("~/.vimrc");
        if (f.open(QIODevice::ReadOnly))
        {
                qDebug() << f.readAll();
                f.close();
        }
        else
        {
                qDebug() << f.error();
        }
}
#包括
#包括
int main()
{
QFile f(“~/.vimrc”);
if(f.open(QIODevice::ReadOnly))
{

qDebug()它与不支持UNIX无关;将tilde扩展到用户的主目录是由shell执行的替换,因此是的,您必须手动替换它们。

看看C库函数
glob
,它将执行tilde扩展(可能还有通配符扩展和其他各种函数)。

您只需创建一个助手函数即可完成此操作,例如:

QString morphFile(QString s) {
    if ((s == "~") || (s.startsWith("~/"))) {
        s.replace (0, 1, QDir::homePath());
    }
    return s;
}
:
QFile vimRc(morphFile("~/.vimrc"));
QFile homeDir(morphFile("~"));
考虑到其他用户的主目录,更完整的解决方案可能是:

QString morphFile(QString fspec) {
    // Leave strings alone unless starting with tilde.

    if (! fspec.startsWith("~")) return fspec;

    // Special case for current user.

    if ((fspec == "~") || (fspec.startsWith("~/"))) {
        fspec.replace(0, 1, QDir::homePath());
        return fspec;
    }

    // General case for any user. Get user name and length of it.

    QString name (fspec);
    name.replace(0, 1, "");           // Remove leading '~'.
    int len = name.indexOf('/');      // Get name (up to first '/').
    len = (len == -1)
        ? name.length()
        : len - 1;
    name = name.left(idx);

    // Find that user in the password file, replace with home
    // directory if found, then return it. You can also add a
    // Windows-specific variant if needed.

    struct passwd *pwent = getpwnam(name.toAscii().constData());
    if (pwent != NULL)
        fspec.replace(0, len+1, pwent->pw_dir);

    return fspec;
}

需要记住的一件事是,当前的解决方案不能移植到Windows(根据代码中的注释)。我怀疑这对于直接的问题是可以的,因为
.vimrc
表明您运行的不是这个平台(它是Windows上的
\u vimrc


为该平台定制解决方案是可能的,并且确实表明helper函数解决方案非常适合,因为您只需更改一段代码即可添加该解决方案。

请向Qt bugtracker提交建议


是的,我知道这是一个shell扩展。但它非常方便,我希望unix Qt实现能够支持并在tilde上扩展。虽然我喜欢这个想法,但在处理“~user”等情况时,它会变得很麻烦。您的代码可能不应该试图在其他用户的目录中摆弄:-)但是,是的,如果你想要完整的扩展,你可能需要到shell中去获取它们。我只是回答了你问题中的特定情况,即
~
。但是,如果你需要整个范围,最好还是将代码隔离到这个单一的帮助函数。如果它只是
~/
,请使用我给出的。如果它是de>~
,在函数中找到另一种方法,例如运行子shell来检索它的值。我看不到一种更简便的方法来做你想做的事情。@paxdiablo:虽然可以使用~user来定义“user”的主目录,但它并不像普通的~那样广泛用于引用你自己的主目录。无论如何,你可以通过查看来检测差异将~作为第一个字符,然后检查第二个字符是否为。与~user打交道会更加混乱……但你至少可以检测到它并抱怨:)好的,我添加了一些(未经测试)代码应该接近于处理其他用户。请记住,它不是线程安全的,如果您需要,您需要使用
\r
版本。事实上,它甚至可能无法编译,但这是一个很好的开始:-)一旦开始工作,请随时编辑(或者让我知道问题,我会自己解决).Cheers.@paxdiablo:如果用户将
~foo/bar.baz
放入配置文件(或在对话框中输入;我过去必须处理这个问题),那么程序员就不能说“不要在别人的主目录中乱动”。将这一点留给操作系统,否则其他用户可能会实际授予该文件的权限。当代码落地时,就会发生这种情况。我想这将涉及到删除其他我不想处理的特殊全局字符。而且我必须以某种方式处理返回列表中的多个条目,因为lob不会返回单个字符串(尽管列表可能只包含一个字符串)。这取决于您的操作系统;例如,OS X有一个GLOB_LIMIT标志,允许您只请求一个结果。对于可能更有用的函数,请尝试
wordexp
,它可以让您完成shell在构造命令时所做的大部分工作。实现
操作符/(QDir,std::string)可能是值得的
这样您就可以编写
QDir::homePath()/“.vimrc”