• 検索結果がありません。

便利な関数

ドキュメント内 表紙 (ページ 44-50)

第 3 章 GLib 31

3.2 便利な関数

ここではGLibで提供されている関数をカテゴリ別にいくつか紹介します.

3.2.1 文字列操作関数

g strdup

文字列をコピーして,新しく確保した領域へのポインタを返します. g c h a r* g _ s t r d u p (c o n s t g c h a r * s t r ) ;

g strdup printf

指定したフォーマットと引数に与えたパラメータにより文字列を作成して, 新しく確保した領域へのポ インタを返します. sprintfと同じ働きをしますが, 予め作成される文字列用の領域を確保しておく必要 がありません.

g c h a r* g _ s t r d u p _ p r i n t f (c o n s t g c h a r * f o r m a t , v a _ l i s t a r g s ) ;

表3.1 GLibで定義された基本データ型

GLibで定義されたデータ型 対応する基本データ型

gboolean gint

gpointer void*

gconstpointer const void *

gchar char

guchar unsigned char

gint int

guint unsigned int

gshort short

gushort unsigned short

glong long

gulong unsigned long

gint8 signed char

guint8 unsigned char

gint16 signed short

guint16 unsigned short

gint32 signed int

guint32 unsigned int

gfloat float

gdouble double

g strsplit

文字列stringを区切り文字delimiterで最大max tokens個に分割する関数です. g c h a r* * g _ s t r s p l i t (c o n s t g c h a r * s t r i n g ,

c o n s t g c h a r * d e l i m i t e r , g i n t m a x _ t o k e n s ) ;

g new0

指定したデータ型struct typeのメモリ領域をn structs分確保し, 0で初期化して,その先頭アドレス を返します. この関数はg malloc0のマクロとして定義されています.

# d e f i n e g _ n e w 0 ( s t r u c t _ t y p e , n _ s t r u c t s ) \

( ( s t r u c t _ t y p e * ) g _ m a l l o c 0 ( ( (g s i z e) s i z e o f ( s t r u c t _ t y p e ) ) * \ ( (g s i z e) ( n _ s t r u c t s ) ) ) )

g p o i n t e r g _ m a l l o c 0 (g u l o n g n _ b y t e s ) ;

g free

マクロg new0等で確保されたメモリ領域を解放する関数です.

v o i d g _ f r e e (g p o i n t e r m e m ) ;

g strfreev

g strsplit等で確保された文字列の配列領域を解放する関数です.

v o i d g _ s t r f r e e v (g c h a r * * s t r _ a r r a y ) ;

3.2.2 ファイルアクセス関数

g file test

GFileTestで定義されたファイルの状態を調べる関数です. 第2引数に与える値によって,ファイルが

存在するか,ファイルがディレクトリであるかなどを調べることができます.

g b o o l e a n g _ f i l e _ t e s t (c o n s t g c h a r * f i l e n a m e , G F i l e T e s t t e s t ) ;

GFileTestは次のように定義されています.

t y p e d e f e n u m {

G _ F I L E _ T E S T _ I S _ R E G U L A R = 1 < < 0 , G _ F I L E _ T E S T _ I S _ S Y M L I N K = 1 < < 1 , G _ F I L E _ T E S T _ I S _ D I R = 1 < < 2 , G _ F I L E _ T E S T _ I S _ E X E C U T A B L E = 1 < < 3 , G _ F I L E _ T E S T _ E X I S T S = 1 < < 4 } G F i l e T e s t;

g dir open

ディレクトリをオープンする関数です. オープンしたディレクトリ内のファイル名を調べるには次の関 数g dir read nameを使用します.

G D i r* g _ d i r _ o p e n (c o n s t g c h a r * p a t h ,

g u i n t f l a g s ,

G E r r o r * * e r r o r ) ;

g dir read name

関数g dir openでオープンしたディレクトリ内のファイル名を調べる関数です. 呼び出されるごとに順

にファイル名を返していきます. 最後まで読み込んだ場合はNULLが帰ります. G _ C O N S T _ R E T U R N g c h a r* g _ d i r _ r e a d _ n a m e (G D i r * d i r ) ;

g dir close

関数g dir openでオープンしたディレクトリをクローズする関数です.

v o i d g _ d i r _ c l o s e (G D i r * d i r ) ;

サンプルプログラム

上記の関数を使用したプログラムの例をソース3–1に示します. このプログラムは引数に指定したディレク トリ内のファイルの一覧を表示するプログラムです.

ディレクトリのオープン(15行目)

関数g dir openの第1引数にオープンするディレクトリ名を指定してディレクトリをオープンします. 現在

の仕様では第2引数には0のみを指定することになっています. 第3引数にはGError構造体へのポインタを 指定しますが, エラーの詳細が必要ない場合にはNULLを与えておけばよいでしょう. ディレクトリのオープ ンに失敗するとNULLが返ってきます.

ディレクトリ内のファイルの表示(17–22行目)

17行目からのwhileループでは,関数g dir read nameによってオープンしたディレクトリ内のファイル名 を一つずつ取得していきます. そして関数g file testでファイルがディレクトリかどうか調べるために,関数 g build filenameを使用してファイル名にパスを追加しています. 関数g build filenameではファイル名用の メモリ領域が新しく領域確保されますので, 21行目で関数g freeで使用しなくなったメモリ領域を解放してい ます.

ディレクトリのクローズ(23行目)

最後に関数g dir closeでディレクトリをクローズしています.

以下にプログラムの実行結果を示します.

% gcc file-sample.c -o file-sample ‘pkg-config --cflags --libs glib-2.0‘

% ./file-sample . file-sample.c (file) file-sample.o (file) testfolder (folder) file-sample (file) Makefile (file)

%

ソース3–1 ファイル操作の例: file-sample.c

1 # i n c l u d e <g l i b . h >

2 # i n c l u d e <s t d l i b . h >

3

4 i n t m a i n (i n t ar g c , c h a r * a r g v [ ] ) {

5 G D i r * d i r ;

6 c o n s t g c h a r * n a m e ;

7 g c h a r * p a t h , * c u r r e n t d i r ;

8 g b o o l e a n i s _ d i r ;

9

10 i f ( a r g c ! = 2 ) {

11 g _ p r i n t ( " U s a g e : à . / f i l e - s a m p l e . c à d i r e c t o r y \ n " ) ;

12 e x i t ( 1 ) ;

13 }

14 c u r r e n t d i r = a r g v [ 1 ] ;

15 d i r = g _ d i r _ o p e n ( c u r r e n t d i r , 0 , N U L L ) ;

16 i f ( d i r ) {

17 w h i l e ( n a m e = g _ d i r _ r e a d _ n a m e ( d i r ) ) {

18 p a t h = g _ b u i l d _ f i l e n a m e ( c u r r e n t d i r , n a m e , N U L L ) ;

19 i s _ d i r = g _ f i l e _ t e s t ( p a t h , G _ F I L E _ T E S T _ I S _ D I R ) ;

20 g _ p r i n t ( " % s \ t ( % s ) \ n " , n a m e , ( i s _ d i r ) ? " f o l d e r " : " f i l e " ) ;

21 g _ f r e e ( p a t h ) ;

22 }

23 g _ d i r _ c l o s e ( d i r ) ;

24 }

25 r e t u r n 0 ;

26 }

3.2.3 Unicode に関する関数

g locale to utf8

C言語中で文字列用のエンコーディングで与えられた文字列をUTF8でエンコーディングされた文字 列に変換する関数です. この関数によって新しい文字列用のメモリ領域が確保されますので,作成した 文字列が使用されなくなった場合には関数g freeなどでメモリ領域を解放してください.

g c h a r* g _ l o c a l e _ t o _ u t f 8 (c o n s t g c h a r * o p s y s s t r i n g ,

g s s i z e len ,

g s i z e * b y t e s _ r e a d , g s i z e * b y t e s _ w r i t t e n , G E r r o r * * e r r o r ) ;

g locale from utf8

UTF8でエンコーディングされた文字列をC言語中で文字列用のエンコーディングに変換する関数で す. この関数によって新しい文字列用のメモリ領域が確保されますので, 作成した文字列が使用されな くなった場合には関数g freeなどでメモリ領域を解放してください.

g c h a r* g _ l o c a l e _ f r o m _ u t f 8 (c o n s t g c h a r * u t f 8 s t r i n g ,

g s s i z e len ,

g s i z e * b y t e s _ r e a d , g s i z e * b y t e s _ w r i t t e n , G E r r o r * * e r r o r ) ;

サンプルプログラム

GTK+のウィジェット内で扱われる文字コードはUTF8です. しかし, 関数g dir openなどで読み出した ファイル名やプログラムの引数として与えた文字列などは,ロケール指定の文字コードとなります. ここでは, プログラムの引数として与えた文字列をそのままラベルとして表示した場合と,文字コードをUTF8に変換し てラベルとして表示した場合を比較してみます. 図3.1はプログラムの実行例です.

% gcc utf8-sample.c -o utf8-sample ‘pkg-config --cflags --libs glib-2.0‘

% ./utf8-sample こんにちは世界

上のラベルはプログラムの引数に与えた文字列”こんにちは世界” をそのまま使用したラベルです. 下のラ ベルはプログラムの引数に与えた文字列の文字コードを関数g locale to utf8でUTF8に変更して使用したラ ベルです. 関数の第2引数には変換する文字列の長さを指定しますが,文字列を全て変換する場合には1を

与えても構いません. 第3引数から第5引数までは通常NULLを指定しておいても構いません.

ソース3–2 文字コード変換: utf8-sample.c

1 # i n c l u d e <g t k / g t k . h >

2 # i n c l u d e <s t d l i b . h >

3

4 i n t m a i n (i n t ar g c , c h a r * a r g v [ ] ) {

5 G t k W i d g e t * w i n d o w , * l a b e l , * v b o x ;

6 g c h a r * n a m e , * u t f 8 n a m e ;

7

8 i f ( a r g c ! = 2 ) {

9 g _ p r i n t ( " U s a g e : à . / u t f 8 - s a m p l e . c às t r i n g \ n " ) ;

10 e x i t ( 1 ) ;

11 }

12 g t k _ i n i t ( & a r g c , & a r g v ) ;

13

14 w i n d o w = g t k _ w i n d o w _ n e w ( G T K _ W I N D O W _ T O P L E V E L ) ;

15 g t k _ w i n d o w _ s e t _ t i t l e ( G T K _ W I N D O W ( w i n d o w ) , " U T F 8 Ã S a m p l e " ) ;

16 g _ s i g n a l _ c o n n e c t ( G _ O B J E C T ( w i n d o w ) ,

17 " d e s t r o y " , G _ C A L L B A C K ( g t k _ m a i n _ q u i t ) , N U L L ) ;

18

19 v b o x = g t k _ v b o x _ n e w ( T R U E , 0 ) ;

20 g t k _ c o n t a i n e r _ a d d ( G T K _ C O N T A I N E R ( w i n d o w ) , v b o x ) ;

21

22 n a m e = a r g v [ 1 ] ;

23 l a b e l = g t k _ l a b e l _ n e w ( n a m e ) ;

24 g t k _ b o x _ p a c k _ s t a r t ( G T K _ B O X ( v b o x ) , l a b e l , T R U E , T R U E , 0 ) ;

25

26 u t f 8 n a m e = g _ l o c a l e _ t o _ u t f 8 ( n a m e , -1 , N U L L , N U L L , N U L L ) ;

27 l a b e l = g t k _ l a b e l _ n e w ( u t f 8 n a m e ) ;

28 g t k _ b o x _ p a c k _ s t a r t ( G T K _ B O X ( v b o x ) , l a b e l , T R U E , T R U E , 0 ) ;

29 g _ f r e e ( u t f 8 n a m e ) ;

30

31 g t k _ w i d g e t _ s h o w _ a l l ( w i n d o w ) ;

32 g t k _ m a i n ( ) ;

33

34 r e t u r n 0 ;

35 }

図3.1 文字コード変換のサンプルプログラム

3.2.4 その他の便利な関数

g get home dir

ユーザのホームディレクトリを取得する関数です.

G _ C O N S T _ R E T U R N g c h a r* g _ g e t _ h o m e _ d i r (v o i d) ;

g get current dir

現在のディレクトリを取得する関数です.

g c h a r* g _ g e t _ c u r r e n t _ d i r (v o i d) ;

g path get basename

パスから最後のファイル名を返します. パスがディレクトリを指す場合には最後のディレクトリ名を返 します.

g c h a r* g _ p a t h _ g e t _ b a s e n a m e (c o n s t g c h a r * f i l e _ n a m e ) ;

g path get dirname

パスから最後のファイル名を取り除いたディレクトリ部分を返します. g c h a r* g _ p a t h _ g e t _ d i r n a m e (c o n s t g c h a r * f i l e _ n a m e ) ;

g build filename

引数に与えた文字列をファイル名用の区切り文字(例えば/)で結合して, 1つの文字列を作成します. 引 数の最後はNULLで終わる必要があります.

g c h a r* g _ b u i l d _ f i l e n a m e (c o n s t g c h a r * f i r s t _ e l e m e n t , . . . ) ;

ドキュメント内 表紙 (ページ 44-50)