Is there QPath::Combine in QT4?

Gad D Lord picture Gad D Lord · Aug 22, 2010 · Viewed 15.9k times · Source

I need a similar to .NET method for safely combining path parts without worrying for platform specifics of the path separator.

Is there such class and method in QT4?

Something like:

QPath::Combine

Answer

Adriano Repetti picture Adriano Repetti · Oct 22, 2012

There is not any function that can be used as direct replacement for Path.Combine() so you have to write it by your own.

You may do it in the hard way (handling everything by yourself) or simply use QDir::cleanPath():

QString pathAppend(const QString& path1, const QString& path2)
{
    return QDir::cleanPath(path1 + QDir::separator() + path2);
}

I used QDir::separator() but as pointed out in Cross-platform way of constructing a FS path with Qt you do not really need it and you simply can use the /. QDir::cleanPath() will remove double / (or double \, according to QDir::separator()) and will resolve . and .. to appropriate values. See also Qt equivalent of PathAppend? for code about QT PathAppend() replacement.

As said it mimics PathAppend() native function (see MSDN) but this is not an exact replacement of Path.Combine() because Path.Combine() doesn't perform an cleaning or normalization (it just appends strings, handling directory separators in the proper way, see MSDN). If you need an exact replacement you may use this one:

QString pathCombine(const QString& path1, const QString& path2)
{
    if (path2.startsWith(QDir::separator()))
        return path2;

    return trimEnd(path1, QDir::separator())
        + QDir::separator()
        + trim(path2, QDir::separator());
}

This function will not add a trailing directory separator if path2 is a directory name (it doesn't perform any check and path may even not exist at all). Also note that path2 must be a sub-path of path1 (relative paths upper than path1 aren't supported, if you need them you have to use previous version with QDir::cleanPath()), also if path2 is rooted then path2 is returned (this implementation is pretty naive, for example it doesn't detect c:\directory as a rooted path).

trim() and trimEnd() functions remove trailing directory separator (for a possible, generic, implementation see How do I remove trailing whitespace from a QString? as starting point). Algorithm to ensure there is a trailing directory separator is same one described in How to ensure there is trailing directory separator in paths? (simplified because here we always have one directory separator given by QDir::separator()).