basename, dirname -
パス名を解析して各部分を取り出す
#include <libgen.h>
char *dirname(char *path);
char *basename(char *path);
警告:
basename()
には異なるバージョンが
2つ存在する。下記の「注意」の節を参照のこと。
dirname() と
basename()
は、ヌルで終端されたパス名の文字列を、
ディレクトリ部分・ファイル名部分に分割する。
通常は、
dirname()
は最後の '/' までの部分
(最後の '/' は含まない)
を返し、
basename()
は最後の '/'
以降の部分を返す。
文字列の末尾についた
'/'
文字は、パス名の一部とはみなされない。
path に '/'
文字がない場合は、
dirname() は文字列 "."
を返し、
basename() は
path
と同じ内容を返す。
path が文字列 "/"
に等しい場合は、
dirname() も
basename() も文字列
"/" を返す。
path が
ヌルポインターだったり、空の文字列を指していた場合は、
dirname() も
basename() も文字列
"." を返す。
dirname()
の返した文字列、
"/"、
basename()
の返した文字列、
を順に結合すると、完全なパス名が得られる。
dirname() と
basename()
は、いずれも
path
の内容を変更することがある。
したがって、これらの関数を呼び出す際には
コピーを渡すのが望ましい。
これらの関数は、静的に割り当てられたメモリーへのポインターを返すことがあり、
これらの領域は後の関数呼び出しで上書きされるかもしれない。
また、これらの関数は
path
の一部分を指すポインターを返すこともある。そのため、
path
で参照される文字列は、関数が返すポインターが不要になるまでは
変更したり free
したりすべきではない。
以下の一連の例 (SUSv2
から引用) は、
いろいろな path に対して
dirname() と
basename()
が返す文字列を表したものである。
path |
dirname |
basename |
|
/usr/lib |
/usr |
lib |
|
/usr/ |
/ |
usr |
|
usr |
. |
usr |
|
/ |
/ |
/ |
|
. |
. |
. |
|
.. |
. |
.. |
|
dirname() と
basename()
は、いずれもヌルで終端された文字列へのポインターを返す。
(これらのポインターを
free(3)
に渡さないこと。)
この節で使用されている用語の説明については、
attributes(7) を参照。
インターフェース |
属性 |
値 |
basename(), dirname() |
Thread safety |
MT-Safe |
POSIX.1-2001, POSIX.1-2008.
basename() には
2種類の異なるバージョンがある。
一つはすでに説明した
POSIX バージョンであり、
もう一つは GNU
バージョンである。 GNU
バージョンを使用するには以下のようにする。
#define _GNU_SOURCE /* feature_test_macros(7) 参照 */
#include <string.h>
GNU
バージョンは引数を変更することはなく、
path の末尾が
'/'の場合は空の文字列を返す。
特に
path が "/"
の場合も空文字列を返す。
dirname() には GNU
バージョンはない。
glibc では、
<libgen.h>
をインクルードすると
POSIX バージョンの
basename()
が使用され、それ以外の場合は
GNU バージョンとなる。
glibc
の実装では、これらの関数の
POSIX バージョンは
path
引数が変更され、
"/usr/"
などの静的文字列を指定されるとセグメンテーションフォールトを起こす。
バージョン 2.2.1 以前の glibc
では、 glibc の
dirname()
は末尾が '/'
文字になっているパス名を正しく扱えず、
引数が NULL
だとセグメンテーションフォールトを起こした。
The following code snippet demonstrates the use of
basename() and
dirname():
char *dirc, *basec, *bname, *dname;
char *path = "/etc/passwd";
dirc = strdup(path);
basec = strdup(path);
dname = dirname(dirc);
bname = basename(basec);
printf("dirname=%s, basename=%s\n", dname, bname);
basename(1),
dirname(1)
この man ページは Linux
man-pages
プロジェクトのリリース
5.10
の一部である。プロジェクトの説明とバグ報告に関する情報は
https://www.kernel.org/doc/man-pages/
に書かれている。