2015-09-22 104 views
0

我目前在操作系统类中。我们的一个项目涉及创建一个简单的shell。这涉及解析行并解析路径。所以我需要考虑像〜这样的事情。 ../etc ..现在我正试图想出一个用于轻松解决“..” - 父目录的代码。C中的Unix路径分辨率

这是我的代码到目前为止。我的目标是找到..的一个事件,然后保存字符串的后半部分(如果有的话),然后剥离..以及到第二个“/”之前。因此,例如我们有: /1/2/3/../../4/5/6 我的目标是,在..的第一个位置保存/../4/5/6 和然后保存1/2并连接。 那么就应该寻找下一个..和保存/ 4/5/6到下半年 和上半年应该保存/ 1

void expandParentDirectory(){ 

char firstHalf[ 255 ]; 
char secondHalf[ 255 ]; 

for(int i = 1; i < tokenSize; i++){ 

    // checking token list for appearance of ".." 
    ////// tests 
    size_t len = strlen(parsedArguments[i]); 
    printf("string length is: %lu \n", len); 

    for(int j = 0; j < strlen(parsedArguments[i]); ++j){ 
     if(parsedArguments[ i ][ j ] == '.') 
      if(parsedArguments[ i ][ j + 1 ] == '.'){ 

       if(parsedArguments[ i ][ j + 2 ] != '\0'){ 
        strcpy(secondHalf, &parsedArguments[ i ] [ j + 2 ]); 
       } 
       // code to expand PWD and move up a directory 
       // if (j == 0) {} 

       for (int k = j - 2 ; k > 0 ; k--) { 
        if(parsedArguments[ i ][ k ] == '/'){ 
         strncpy(firstHalf, parsedArguments[ i ], k); 
         //firstHalf[ k ] = '\0'; 

         free (parsedArguments[ i ]); 
         parsedArguments[ i ] = strdup(strcat(firstHalf, secondHalf 
        } 
       } 
       )); 


      } 
    } 
} 
} 

上得到这个任何建议正常工作? 有关更好方法的任何建议? 谢谢!

+0

欢迎来到Stack Overflow。请尽快阅读[关于]页面。你应该发布可编译的代码;你已经发布的内容明显无法编译,因为''));'在最内层的'for'循环之后。你的'strdup(strcat(')行似乎缺少这些字符,你可能最好在字符串中寻找'/../'('strstr()');这更简单明确地寻找你想要的东西。目前,你会滥用'/ abc/def ../ ghi'这是一个完全合法的路径,不需要进行路由。你还需要将这个抽象成一个传递给'parsedArguments [i]'的函数。 –

+1

请注意,字符串永远不会增长;你不需要使用'strdup()'。 –

回答

0

尽管真实路径之美()(或我猜是因为它)我无法在我的代码中使用它。我必须做我自己的工作。这是我想出的。它工作得很好,但绝不是完美的。我不确定是否是这个代码或调用它的代码,但是当重复设置目录或者用..调用某个目录时,我会遇到很多错误。除了这些问题,我还是非常喜欢它。

char * pathResolution (char * path){ 

char * specialDirectory[ 3 ] = { ".", "..", "~" }; 
char * currentPath = getenv("PWD"); 
char * pathTokens[ 50 ]; 

int pathTokenCount = 0; 
int action = -1; 

// if it is just "/", no checks needed 
if(!strcmp("/", path)){ 
    return path; 
} 

// get each path token between '/' 
for (path = strtok(path, "/"); path; 
    path = strtok(NULL, "/")) { 
    pathTokens[ pathTokenCount++ ] = path; 
} 

// check for special characters 
for(size_t i = 0; i != pathTokenCount; ++i) { 

    // checks for special characters; sets action 
    if(!strcmp(specialDirectory[ 0 ], pathTokens[ i ])){ action = 1; } 
    else if(!strcmp(specialDirectory[ 1 ], pathTokens[ i ])){ action = 1; } 
    else if(!strcmp(specialDirectory[ 2 ], pathTokens[ i ])){ action = 2; } 
    else { action = 3; } 

    // action depending on character 
    switch(action){ 

     case 1:{ // ".." 

      int index; 
      char * lastSlash = strrchr(currentPath, '/'); 
      index = (int)(lastSlash - currentPath); 
      currentPath[ index ] = '\0'; 

      if(strlen(currentPath) < 1){ 
       currentPath = "/"; 
      } 
      break; 
     } 

     case 2: { // "~" 

      // ~ can only be first, return null otherwise 
      if(i == 0){ 
       currentPath = getenv("HOME"); 
       break; 
      } 
      else 
       return NULL; 
     } 

     case 3: { 

      // appends /text to end of PWD: PWD/...text... 
      char buffer[ 255 ]; 
      if(!strcmp("/", currentPath)) 
       sprintf(buffer, "/%s", pathTokens[ i ]); 
      else 
       sprintf(buffer, "%s/%s", currentPath, pathTokens[ i ]); 

      currentPath = buffer; 
      break; 
     } 

     default: 
      break; 

    } 
} 

return currentPath; 

} 
0

库函数realpath会为你做到这一点:http://man7.org/linux/man-pages/man3/realpath.3.html

+0

是的,'realpath'将在一种流行之后完成这项工作,但这显然不是练习。也解决了这个代码没有的符号链接;它只是在纯粹的文本“路径解析” –

+0

@JonathanLeffler - 这是来自Solaris 11上用于实际路径的手册页:realpath()函数从指定的路径名​​ 通过file_name命名一个绝对路径名称e 文件,其分辨率不涉及“。”,“..”或sym-bolic链接。生成的路径名存储为由 resolved_name指向的缓冲区中的一个NULL- 终止字符串,最大值为{PATH_MAX}字节 (在limits.h(3HEAD)中定义)。 - 请注意它不能解析符号链接 –

+0

@jimmcnamara:au contraire:它明确指出,即使输入确实遍历符号链接,结果路径也不包含符号链接 - 请参阅引用的文本。 –