Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Path/Directory separator inconsistent.



  • I get the current working directory using:

    QDir::currentPath().toLatin1().data()
    

    This returns :

    C:/Users/simon/Documents/ProjectName/build-ProjectName-Desktop_Qt_5_8_0_MSVC2013_32bit-Debug
    

    I then test the path to see if it needs a trailing separator:

    QChar separator = QDir::separator();
    if (!path.endsWith(separator) {
        path += separator;
    }
    

    The separator returned by QDir::separator() is not the same as the separator returned by QDir::currentPath(), why is this?

    Separator contains:

    '\' (92)
    

    When its appended to the path, the new path is:

    C:/Users/simon/Documents/ProjectName/build-ProjectName-Desktop_Qt_5_8_0_MSVC2013_32bit-Debug\
    

    After seeing this I then appended a separator on the path before the test just to see what happens. Now this is where the problem exists because the test for endsWith return false and then the path is modified to:

    C:/Users/simon/Documents/ProjectName/build-ProjectName-Desktop_Qt_5_8_0_MSVC2013_32bit-Debug\/


  • @SPlatten said in Path/Directory separator inconsistent.:

    The separator returned by QDir::separator() is not the same as the separator returned by QDir::currentPath(), why is this?

    This is explained in QDir documentation, please take time to read documentation:

    A QDir is used to manipulate path names, access information regarding paths and files, and manipulate the underlying file system. It can also be used to access Qt's resource system.

    Qt uses "/" as a universal directory separator in the same way that "/" is used as a path separator in URLs. If you always use "/" as a directory separator, Qt will translate your paths to conform to the underlying operating system.

    A QDir can point to a file using either a relative or an absolute path. Absolute paths begin with the directory separator (optionally preceded by a drive specification under Windows). Relative file names begin with a directory name or a file name and specify a path relative to the current directory.


  • Moderators

    @SPlatten from the documentation

    https://doc.qt.io/qt-5/qdir.html#separator

    
    Returns the native directory separator: "/" under Unix and "\" under Windows.
    
    You do not need to use this function to build file paths. If you always use "/", Qt will translate your paths to conform to the underlying operating system. 
    

    You have to thank Windows for that, that said, see the last part of the sentence, Simply use QChar('/') and you're always fine (in Qt)



  • @J-Hilk , thats the point I'm making, I'm developing on a Windows 10 laptop with Qt and it always returns "/", it does not return "" under Windows.



  • @KroMignon , that doesn't help because as my example proves, if the path already ends with "/" then it still appends "\".


  • Moderators



  • @J-Hilk , why do I need to call another function in order to correct it? Surely the intuitive thing would be for the separator just to return the correct separator or test the content and return whatever is already being used.



  • @SPlatten said in Path/Directory separator inconsistent.:

    , that doesn't help because as my example proves, if the path already contains "/" then it still appends "".

    As written in documentation, with QDir separator will always be '/', QDir::separator() will give you the system path separator. There is no link between them!

    So if you variable path is filled with a return value from QDir, QFile, QFileInfo, checking them with QDir::separator() is a nonsense. It will fails on every Windows system.



  • @SPlatten said in Path/Directory separator inconsistent.:

    Surely the intuitive thing would be for the separator

    Because then Qt paths, like C:/Users/simon/Documents/ProjectName/build-ProjectName-Desktop_Qt_5_8_0_MSVC2013_32bit-Debug, would never return a separator if you searched them for it.

    As others have said:

    • QDir::separator() will always be / platform-independent, and as used in all internal Qt functions.

    • QDir::toNativeSeparators(QDir::separator()) will return \ under Windows. Which you only need if you're doing something to do with OS commands. What else do you actually need it for?

    Why does this irk you so, seems fine to me?


  • Moderators

    @SPlatten said in Path/Directory separator inconsistent.:

    @J-Hilk , why do I need to call another function in order to correct it? Surely the intuitive thing would be for the separator just to return the correct separator or test the content and return whatever is already being used.

    Nono, you're comparing Apple and Oranges!

    QDir::currentPath().toLatin1().data()

    returns a Qt conform string with '/' as separators than you check with

    QChar separator = QDir::separator();

    if '\' is the ending that can't work.

    After seeing this I then appended a separator on the path before the test just to see what happens.

    this is still confusing, can you show what exactly you'Re doing here ?



  • @J-Hilk , this was the code:

    QChar separator = QDir::separator();
    QString newPath(path);
    
    if (!newPath.endsWith(separator)) {
        newPath += separator;
    }
    

    @JonB, you can't pass QDir::separator() to QDir::toNativeSeparators as there is only one version of this function and it expects a QString not a QChar.

    It's all just messy and requires thought and effort when it should be handled internally.


  • Moderators

    @SPlatten said in Path/Directory separator inconsistent.:

    It's all just messy and requires thought and effort when it should be handled internally.

    it is handled internally, thats the point. The only possibly confusing point could be, that QDir has no QDir::QtSeperator() that returns a QChar('/'); that you could use.

    Simply write

    QChar separator('/');
    if (!path.endsWith(separator) {
        path += separator;
    }
    

    and use toNativeSeperators, if you actually need the native part, for example to display the path or to hand it of to an external non qt program



  • @SPlatten said in Path/Directory separator inconsistent.:

    It's all just messy and requires thought and effort when it should be handled internally.

    There is no mess here, it is clearly documented:

    • QDir always use '/' as path separator. So path string can the same on every system for which your application is build
    • QDir::separator() gives you the system path separator on which application is running
    • QDir::toNativeSeparators(), will convert the given string to a string using QDir::separator() so it will be acceptable by the system.
    • QDir:cleanPath(), will ensure you path has no redondant separators, and use '/' as separator

    So your code is wrong.
    This could work:

    QString newPath(QDir::cleanPath(path));
    
    if (!newPath.endsWith('/')) {
        newPath += '/';
    }
    


  • @KroMignon , I'm writing an application that uses paths that may be supplied in text files, the application should not rely on what the Qt library uses.



  • @SPlatten said in Path/Directory separator inconsistent.:

    I'm writing an application that uses paths that may be supplied in text files, the application should not rely on what the Qt library uses.

    And what is the problem with that?
    Simply use QDir:cleanPath() to ensure your path string is correct.



  • @SPlatten said in Path/Directory separator inconsistent.:

    @JonB, you can't pass QDir::separator() to QDir::toNativeSeparators as there is only one version of this function and it expects a QString not a QChar.

    Why do you make this kind of statement without checking?

        QString sep = QDir::toNativeSeparators(QDir::separator());
    
    


  • I did exactly that, in the version of Qt Creator I'm using there is only one function.



  • @SPlatten
    No, you did not try the code! There is just the one function in my version of Qt too! And it accepts the same parameter type as yours.... static QString toNativeSeparators(const QString &pathName);, https://doc.qt.io/qt-5/qdir.html#toNativeSeparators.



  • @JonB , Qt Creator 4.2.1, Based on Qt 5.8.0 (MSCV 2015, 32 bit), thats the version on the laptop I'm using for this project and I can sure you that the version only excepts a const QString&, there is no alternative in this IDE.



  • @SPlatten
    It has nothing to do with the IDE, at all.

    I can sure you

    It does have to do with the behaviour of C++, and QString....

    Would you be kind enough to copy & paste my line into your version, and tell me the outcome, please? Show me the error message you get at compile-time, thank you.



  • @JonB , QDir::separator does not return a QString it returns a QChar.



  • @SPlatten
    I KNOW THIS.

    HAVE YOU ACTUALLY TRIED IT, DESPITE WHAT YOU SAY??????????



  • @JonB How can I try it when it won't compile without errors? Stop shouting and calm down!



  • @SPlatten
    Could you please put it into your code, and show me the compile-time error message you get, as requested? I should be most obliged....


  • Qt Champions 2019

    @SPlatten Sorry, but I have to support @JonB here: that line of code compiles just fine.
    "it returns a QChar" - which converts just fine to a QString (https://doc.qt.io/qt-5/qstring.html#QString-2).



  • @JonB , sorry, I just don't have time to back tract now, apologies if I was wrong.


Log in to reply