How to extract filename from path

后端 未结 10 1843
遥遥无期
遥遥无期 2020-12-15 03:26

There should be something elegant in Linux API/POSIX to extract base file name from full path

10条回答
  •  时光说笑
    2020-12-15 03:31

    @Nikolay Khilyuk offers the best solution except.

    1) Go back to using char *, there is absolutely no good reason for using const.

    2) This code is not portable and is likely to fail on none POSIX systems where the / is not the file system delimiter depending on the compiler implementation. For some windows compilers you might want to test for '\' instead of '/'. You might even test for the system and set the delimiter based on the results.

    The function name is long but descriptive, no problem there. There is no way to ever be sure that a function will return a filename, you can only be sure that it can if the function is coded correctly, which you achieved. Though if someone uses it on a string that is not a path obviously it will fail. I would have probably named it basename, as it would convey to many programmers what its purpose was. That is just my preference though based on my bias your name is fine. As far as the length of the string this function will handle and why anyone thought that would be a point? You will unlikely deal with a path name longer than what this function can handle on an ANSI C compiler. As size_t is defined as a unsigned long int which has a range of 0 to 4,294,967,295.

    I proofed your function with the following.

        #include 
        #include 
    
        char* getFileNameFromPath(char* path);
    
        int main(int argc, char *argv[])
        {
            char *fn;
    
            fn = getFileNameFromPath(argv[0]);
            printf("%s\n", fn);
            return 0;
        }
    
        char* getFileNameFromPath(char* path)
        {
           for(size_t i = strlen(path) - 1; i; i--)  
           {
                if (path[i] == '/')
                {
                    return &path[i+1];
                }
            }
            return path;
        }
    

    Worked great, though Daniel Kamil Kozar did find a 1 off error that I corrected above. The error would only show with a malformed absolute path but still the function should be able to handle bogus input. Do not listen to everyone that critiques you. Some people just like to have an opinion, even when it is not worth anything.

    I do not like the strstr() solution as it will fail if filename is the same as a directory name in the path and yes that can and does happen especially on a POSIX system where executable files often do not have an extension, at least the first time which will mean you have to do multiple tests and searching the delimiter with strstr() is even more cumbersome as there is no way of knowing how many delimiters there might be. If you are wondering why a person would want the basename of an executable think busybox, egrep, fgrep etc...

    strrchar() would be cumbersome to implement as it searches for characters not strings so I do not find it nearly as viable or succinct as this solution. I stand corrected by Rad Lexus this would not be as cumbersome as I thought as strrchar() has the side effect of returning the index of the string beyond the character found.

    Take Care

提交回复
热议问题