簡體   English   中英

ANSI C中的字符串處理

[英]String handling in ANSI C

假設我收到以下路徑

char* path = "home/directory/file.txt"

我如何處理此字符串以獲取file.txt的父目錄以獲取此字符串

"home/directory"

我想編碼這樣的東西

char* _get_ParentDir(char* file_path);

並且該函數將返回父級的路徑。

首先,不要給函數起一個下划線。 此類標識符保留給實現。

根據您的描述,您可以將最后一個/字符替換為空字符:

char *last_slash = strrchr(path, '/');
if (last_slash != NULL) {
    *last_slash = '\0';
}

這樣就可以修改字符串了,但是您需要一個函數。 編寫一個返回指向字符串的指針的函數很棘手。 您不必擔心為字符串分配空間。 共有三種常見方法:

  1. 在函數中聲明一個static數組,並返回一個指向其第一個元素的指針。 問題:每次調用該函數都會破壞以前的調用所使用的緩沖區。

  2. 讓調用者將指針傳遞到將結果寫入其中的緩沖區。 這使調用者的事情變得更加復雜。

  3. 讓函數使用malloc()分配緩沖區(並確保檢查分配失敗)。 這是可行的,但是它使調用方稍后負責free()緩沖區。

您的系統可能還會提供為您執行此操作的功能。 另一個答案提到<libgen.h>中的dirname()函數。 這是由POSIX指定的,但不是由C標准指定的; 您的系統可能有也可能沒有。 您應該閱讀手冊頁(如果您使用的是類Unix系統,請閱讀man 3 dirname ),尤其是NOTES部分。

const char* bname=path;
bname+=strlen(path);
while (bname>path && bname[-1]!='\\' && bname[-1]!='/')
   --bname;

還有basename()函數,但是我的版本適用於DOS和Unix / Linux路徑。

[編輯:我想提及的是,我與Ernest Friedman-Hill在下面發表他的評論的大約同一時間,我自己發表了以下內容。 之后,我繼續發布剩下的答案。 -phonetagger]糟糕...我向后讀了你的問題。 您需要dirname()函數。 #include <libgen.h>

要么....

const char* dname = strdup(path);
const char* bname = dname;
if (dname)
{
   bname+=strlen(path);
   while (bname>dname && bname[-1]!='\\' && bname[-1]!='/')
      --bname;
   if (bname != dname)
      bname[-1] = '\0';
   else
   {
      bname = path;
      free(dname);
      dname = NULL;
   }
}

請注意,此版本為dname分配了一個新字符串,您可能希望也可能不希望free(),這取決於所需的壽命。 如果在應用程序執行期間需要它,則完全不需要free(),操作系統將在應用程序退出時自動回收進程的整個虛擬地址空間。

還要注意,strdup()是必需的,因為您對char * path的分配是從靜態const字符串初始化程序進行的,該初始化程序很可能在程序的只讀部分中分配(可能是.rodata,具體取決於編譯器)。

僅在最后一個斜杠處粘貼'\\ 0'會對原始字符串產生意想不到的副作用。 為了避免這種情況,您將需要創建另一個字符串:

char* _get_ParentDir(char* file_path) {
    char *c = strrchr(file_path, "/");
    long n = c - file_path;
    char *dir = malloc(n+1); // this will need to be freed later
    dir[n] = 0;
    memcpy(dir, file_path, n);
    return dir;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM