realpath做我需要的,但只有在路径中的文件实际存在的情况下才起作用.
我需要一个从字符串返回归一化路径的函数(例如../some/./directory/a/b/c/../d到some / directory / a / b / d),而不管目录/文件实际存在
基本上等同于Windows上的PathCanonicalize.
这样的功能是否已经存在?
解决方法
我不认为有任何标准库函数可用于此.
您可以在Apache httpd源代码文件server / util.c中使用函数ap_getparents().我相信它的确是你想要的:https://github.com/apache/httpd/blob/trunk/server/util.c#L500
#ifdef WIN32 #define IS_SLASH(s) ((s == '/') || (s == '\\')) #else #define IS_SLASH(s) (s == '/') #endif void ap_getparents(char *name) { char *next; int l,w,first_dot; /* Four paseses,as per RFC 1808 */ /* a) remove ./ path segments */ for (next = name; *next && (*next != '.'); next++) { } l = w = first_dot = next - name; while (name[l] != '\0') { if (name[l] == '.' && IS_SLASH(name[l + 1]) && (l == 0 || IS_SLASH(name[l - 1]))) l += 2; else name[w++] = name[l++]; } /* b) remove trailing . path,segment */ if (w == 1 && name[0] == '.') w--; else if (w > 1 && name[w - 1] == '.' && IS_SLASH(name[w - 2])) w--; name[w] = '\0'; /* c) remove all xx/../ segments. (including leading ../ and /../) */ l = first_dot; while (name[l] != '\0') { if (name[l] == '.' && name[l + 1] == '.' && IS_SLASH(name[l + 2]) && (l == 0 || IS_SLASH(name[l - 1]))) { int m = l + 3,n; l = l - 2; if (l >= 0) { while (l >= 0 && !IS_SLASH(name[l])) l--; l++; } else l = 0; n = l; while ((name[n] = name[m])) (++n,++m); } else ++l; } /* d) remove trailing xx/.. segment. */ if (l == 2 && name[0] == '.' && name[1] == '.') name[0] = '\0'; else if (l > 2 && name[l - 1] == '.' && name[l - 2] == '.' && IS_SLASH(name[l - 3])) { l = l - 4; if (l >= 0) { while (l >= 0 && !IS_SLASH(name[l])) l--; l++; } else l = 0; name[l] = '\0'; } }
(这是假设在您的项目中重新使用Apache许可代码是可以接受的.)