2011-04-27 18 views
5

的basename()和目錄名()的使用GNU版本如何使用的basename()dirname() GNU C庫的版本?在C源

如果

#include <libgen.h> 

爲目錄名 你已經得到了POSIX,而不是GNU的basename()版本。 (即使你

#define _GNU_SOURCE 

據我所知,在C.沒有條件進口是否有一個GCC的特殊技巧?

+0

'basename with dirname'對我來說意味着什麼 – sehe 2011-04-27 09:55:41

回答

0

確保您使用的GNU C庫的建設,而不是你。系統(假定)POSIX兼容的默認

這通常是在GCC規範文件中設置使用-v選項顯示當前設置:

$ gcc -v 
Using built-in specs. 
Target: x86_64-linux-gnu 
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.4.4-14ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.4 --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu 
Thread model: posix 
gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5) 
3

根據手冊頁,你應該做

 #define _GNU_SOURCE 
     #include <string.h> 
     #include <libgen.h> 

如果你得到的POSIX版本,libgen.h可能已經包含在該點之前。您可能要包括在CPPFLAGS -D_GNU_SOURCE編譯:

gcc -D_GNU_SOURCE .... 
+0

簡化更具體的答案 – sehe 2011-04-27 10:01:38

+0

3行給我__xpg_basename @@ GLIBC_2.0,沒有libgen給我basename @@ GLIBC_2.0(nm提供)。如果不定義GNU_SO URCE給了我基本名稱@@ GLIBC_2.0但警告初始化時將整數指針不進行強制轉換 – 2011-04-27 10:23:00

+0

我覺得-D_GNU_SOURCE只是做一樣的定義_GNU_SOURCE,如果我兩者都做它警告。 – 2011-04-27 10:28:12

9

自己只寫它,並給它一個不同的名稱basename。 GNU堅持創建可以用1-3行編寫的標準函數的替代不合格版本是完全麻煩的。

char *gnu_basename(char *path) 
{ 
    char *base = strrchr(path, '/'); 
    return base ? base+1 : path; 
} 

這樣,你的程序也會更加便攜。

+3

和你簡單的實現將有以「/」和「/家/我的/」的問題。 – 2011-04-27 13:33:55

+6

這是GNU版本的功能所指定的行爲!見http://www.kernel。org/doc/man-pages/online/pages/man3/basename.3.html「GNU版本從不修改它的參數,並且當路徑有一個斜線時返回空字符串,特別是當它是」/「 「。如果你不想要破壞的GNU行爲,請不要要求它...... – 2011-04-27 13:34:32

+0

好的 - 最好有一個很好的理由讓GNU在自己的切線上脫落。我會記下這個特點。我可以同情'不改變論據'。我有我自己的前綴版本,獲取大小的緩衝區來複制基本名稱,並且它有一個用於輸入的「const char *」參數。 – 2011-04-27 13:40:55

1

檢查libgen.h後,我敢肯定,我有一個無錯無警告的解決方案:

/* my C program */ 
#define _GNU_SOURCE  /* for GNU version of basename(3) */ 
#include <libgen.h>  /* for dirname(3) */ 
#undef basename   /* (snide comment about libgen.h removed) */ 
#include <string.h>  /* for basename(3) (GNU version) and strcmp(3) */ 

/* rest of C program... */ 

隨着#undef線,現在我的計劃包括從libgen.hdirname(3)basename(3) GNU版本從string.h

來自gcc(版本4.5.2)或clang(版本3.3)的編譯器警告/錯誤。