2015-09-22 48 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:它明確指出,即使輸入確實遍歷符號鏈接,結果路徑也不包含符號鏈接 - 請參閱引用的文本。 –