その他

外部 コマンドの実行

system.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
  stdlib.h [system]
  書式: int system(const char *s)
  機能: コマンドプロセッサの存在確認とコマンドの実行
  引数: const char *s: コマンドプロセッサに渡すコマンド (文字列)
        NULL を指定すると, コマンドプロセッサの存在確認ができる.
  戻り値: 引数 s に NULL を指定した場合は, コマンドプロセッサが
          あれば, 0 以外を返し, コマンドプロセッサがなければ 0 を
	  返す.
*/

#include <stdio.h>
#include <stdlib.h>

int main(void){

  printf("mkdir コマンドでフォルダを作成\n");
  system("mkdir commtest");

  printf("ps コマンドを実行する\n");
  system("ps");

  return 0;
}

system.c の実行結果は:

[cactus:~/code_c/refer]% ./system
mkdir コマンドでフォルダを作成
ps コマンドを実行する
  PID TTY           TIME CMD
 1172 ttys000    0:00.13 -tcsh
 1201 ttys000    1:47.24 emacs -nw isdigit.c
 1179 ttys001    0:00.07 -tcsh
 3650 ttys001    0:07.86 emacs -nw c.refer.rst
 1184 ttys002    0:00.07 -tcsh
 3653 ttys002    0:08.46 emacs -nw c.refer.str-op.rst
 1190 ttys003    0:00.10 -tcsh
 7948 ttys004    0:00.13 -tcsh
 8071 ttys004    0:00.00 ./system
 2734 ttys005    0:00.32 -tcsh

フォルダ commtest を確認できる:

[cactus:~/code_c/refer]% ls -F | grep /
commtest/

環境変数の値を取得

getenv.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*
  stdlib.h [getenv]
  書式: char* getenv(const char *s)
  機能: 環境変数の値を取得
  引数: const char *s: 環境変数名
  戻り値: 成功すると, 指定された環境変数の値を返し,
          失敗すると, NULL を返す.
*/

#include <stdio.h>
#include <stdlib.h>

int main(void){

  char *env1;
  char *env2;
  char *env3;

  env1 = getenv("USER");
  env2 = getenv("HOME");
  env3 = getenv("wtopia");

  printf("%s\n", env1);
  printf("%s\n", env2);
  printf("%s\n", env3);
  
  return 0;
}

getenv.c の実行結果は:

[cactus:~/code_c/refer]% ./getenv
Wtopia
/Users/Wtopia
(null)

ロケール (地域と言語) を設定

setlocale.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/*
  locale.h [setlocale, LC_ALL]
  書式: char* setlocale(int cate, const char *locale)
  機能: ロケールを設定する
  引数: int cate: ロケールを設定する為のカテゴリ
        char *locale: ロケール名前
  戻り値: 成功すると, 現在のロケール文字列を返し,
          失敗すると, NULL を返す.
*/

/*
  カテゴリ:
  LC_ALL: 以下の全てカテゴリ
  LC_COLLATE: 文字列の照合 (strcoll, strxfrm)
  LC_CTYPE: 文字処理 (ctype.h)
  LC_MONETARY: 通貨の書式 (localeconv)
  LC_NUMERIC: 小数点や区切りの書式 (printf 等)
  LC_TIME: 日時の書式 (strftime)
*/

/*
  国別コード:
  "JPN": 日本
  "USA": アメリカ
  "FRA": フランス
  "ITA": イタリア
*/

#include <stdio.h>
#include <locale.h>

int main(void){

  char *s;
  float x = 0.001;

  s = setlocale(LC_ALL, NULL);
  printf("現在のロケール %s\n", s);

  s = setlocale(LC_ALL, "JPN");
  printf("現在のロケール %s\n", s);
  printf("%f\n", x);

  s = setlocale(LC_ALL, "FRA");
  printf("現在のロケール %s\n", s);
  printf("%f\n", x);
  
  return 0;
}

setlocale.c の実行結果は:

[cactus:~/code_c/refer]% ./setlocale
現在のロケール C
現在のロケール (null)
0.001000
現在のロケール (null)
0.001000

ロケールの詳細情取得

localeconv.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/*
  locale.h [localeconv, struct lconv]
  書式: struct lconv *localeconv(void)
  機能: 地域の詳細情報の取得
  引数: なし
  戻り値: struct lconv 構造体のポインタを返す.
*/

/*
  struct lconv
  char *decimal_point    : 小数点の文字
  char *thousands_sep    : 数の桁区切り文字
  char *grouping         : 数の区切りを入れる桁数
  char *int_curr_symbol  : 国際通貨記号
  char *currency_symbol  : 地域の通貨記号
  char *mon_decimal_point: 通貨の小数点文字
  char *mon_thousands_sep: 通貨の桁区切り文字
  char *mon_grouping     : 通貨の区切りを入れる桁数
  char *positive_sign    : 通貨の負でない記号
  char *negative_sign    : 通貨の負の記号
  char int_frac_digits   : 国際通貨での小数点桁数
  char frac_digits       : 地域での小数点桁数
  char p_cs_precedes     : 負でない時, 通貨記号が前(1)か後(0)か
  char p_sep_by_space    : 負でない時, 空白で区切る(1)かどうか
  char n_cs_precedes     : 負の時, 通貨記号が前(1)か後(0)か
  char n_sep_by_space    : 負の時, 空白で区切る(1)かどうか
  char p_sign_posn       : 負でない通貨記号の位置
  char n_sign_posn       : 負の通貨記号の位置
*/

#include <stdio.h>
#include <locale.h>

int main(void){
  
  struct lconv *lc;
  
  setlocale( LC_ALL, "JPN" );
  lc = localeconv();

  printf( "decimal_point = %s\n",     lc->decimal_point );
  printf( "thousands_sep = %s\n",     lc->thousands_sep );
  printf( "grouping[0] = %d\n",       lc->grouping[0] );
  printf( "grouping[1] = %d\n",       lc->grouping[1] );
  printf( "grouping[2] = %d\n",       lc->grouping[2] );
  printf( "grouping[3] = %d\n",       lc->grouping[3] );
  printf( "int_curr_symbol = %s\n",   lc->int_curr_symbol );
  printf( "currency_symbol = %s\n",   lc->currency_symbol );
  printf( "mon_decimal_point = %s\n", lc->mon_decimal_point );
  printf( "mon_thousands_sep = %s\n", lc->mon_thousands_sep );
  printf( "mon_grouping[0] = %d\n",   lc->mon_grouping[0] );
  printf( "mon_grouping[1] = %d\n",   lc->mon_grouping[1] );
  printf( "mon_grouping[2] = %d\n",   lc->mon_grouping[2] );
  printf( "mon_grouping[3] = %d\n",   lc->mon_grouping[3] );
  printf( "positive_sign = %s\n",     lc->positive_sign );
  printf( "negative_sign = %s\n",     lc->negative_sign );
  printf( "int_frac_digits = %d\n",   lc->int_frac_digits );
  printf( "frac_digits = %d\n",       lc->frac_digits );
  printf( "p_cs_precedes = %d\n",     lc->p_cs_precedes );
  printf( "p_sep_by_space = %d\n",    lc->p_sep_by_space );
  printf( "n_cs_precedes = %d\n",     lc->n_cs_precedes );
  printf( "n_sep_by_space = %d\n",    lc->n_sep_by_space );
  printf( "p_sign_posn = %d\n",       lc->p_sign_posn );
  printf( "n_sign_posn = %d\n",       lc->n_sign_posn );

  return 0;
}

localeconv.c の実行結果は:

[cactus:~/code_c/refer]% ./localeconv
decimal_point = .
thousands_sep =
grouping[0] = 0
grouping[1] = 37
grouping[2] = 115
grouping[3] = 58
int_curr_symbol =
currency_symbol =
mon_decimal_point =
mon_thousands_sep =
mon_grouping[0] = 0
mon_grouping[1] = 127
mon_grouping[2] = 0
mon_grouping[3] = 0
positive_sign =
negative_sign =
int_frac_digits = 127
frac_digits = 127
p_cs_precedes = 127
p_sep_by_space = 127
n_cs_precedes = 127
n_sep_by_space = 127
p_sign_posn = 127
n_sign_posn = 127

ロケールに応じた文字列比較

strcoll.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
  string.h [strcoll]
  書式: char* strcoll(const char *s1, const char *s2)
  機能: 現在のロケールで文字列の比較
  引数: const char *s1: 比較する文字列
        const char *s2: 比較する文字列
  戻り値: s1 < s2: 負の値
          s1 = s2: 0
	  s1 > s2: 正の値
*/

#include <stdio.h>
#include <string.h>
#include <locale.h>

int main(void){
  
  char *s1 = "ABCD";
  char *s2 = "abcd";
  int ret;

  ret = strcmp(s1, s2);
  printf("%d\n", ret);

  setlocale( LC_COLLATE, "JPN" );
  ret = strcoll(s1, s2);
  printf("%d\n", ret);

  return 0;
}

strcoll.c の実行結果は:

[cactus:~/code_c/refer]% ./strcoll
-32
-32

ロケールに応じた文字列変換

strxfrm

1
2
3
4
5
6
7
8
9
/*
  string.h [strxfrm]
  書式: size_t strxfrm(char *s1, const char *s2, size_t n)
  機能: 現在のロケールで文字列の変換
  引数: char *s1: 変換結果の格納先
        const char *s2: 変換する文字列
	size_t n: 変換する文字数
  戻り値: 変換後の文字列バイト数を返す.
*/

共通の型定義

offsetof

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/*
  stddef.h [offsetof, NULL, size_t, wchar_t, ptrdiff_t]
  書式: size_t offsetof(struct_name, member_name)
  機能: 構造体内で指定したメンバまでのバイト数
  引数: struct_name: 構造体名
        member_name: メンバ名
  戻り値: 指定されたメンバまでのバイト数を返す.
*/

/*
  共通定義:
  NULL: ヌルポインタ
        どのアドレスも指していないポインタ
  size_t: sizeof 演算子や strlen() での戻り値の型
          int 型でも良いが, 長さを明示的に表すため
	  にある
  wchar_t: ワイド文字型
           unsigned short 型で定義されている
	   2 バイト文字を表す為にある
  ptrdiff_t: ポインタ同士の引き算の結果の型
             int 型でも良いが, 同じ配列で, 要素同士が
	     どれくらい離れているかを表す為にある
*/

#include <stdio.h>
#include <stddef.h>

struct test{
  int a;
  float b;
  double c;
  int d;
};

int main(void){
  /* int(4) + float(4) + double(8) = 16 バイト */
  size_t sz = offsetof(struct test, d);
  printf("%d\n", (int)sz);
  
  return 0;
}

offsetof.c の実行結果は:

[cactus:~/code_c/refer]% ./offsetof
16

可変個引数リスト

va_list.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/*
  va_list
  可変個の引数を格納する為の変数 (可変引数リスト)
  実際には, typedef void *va_list: という形で定義されている
*/

/*
  stdarg.h [va_start]
  書式: void va_start(va_list ap, paraNum)
  機能: 可変個引数リストの初期化
  引数: va_list ap: 可変個引数リスト
        paraNum: 初期化する数
  戻り値: なし
*/

/*
  stdarg.h [va_end]
  書式: void va_end(va_list ap)
  機能: 可変個引数リストの終了
  引数: va_list ap: 可変個引数リスト
  戻り値: なし
*/

/*
  stdarg.h [va_arg]
  書式: type va_arg(va_list ap, type)
  機能: 可変個引数リストから指定した型で取得
  引数: va_list ap: 可変個引数リスト
        type: 取得する型
  戻り値: なし
*/


#include <stdio.h>
#include <stdarg.h>

void func(int num, ...);

int main(void){

  func(5, "I", "Can", "Do", "It", "!!");
  
  return 0;
}

void func(int num, ...){
  va_list ap;
  
  int i;
  
  char *str;

  /* 可変引数リスト初期化 */
  va_start(ap, num);

  for(i = 0; i < num; i++){
    /* 可変個の引数を取り出し */
    str = va_arg(ap, char *);
    printf("%s ", str);
  }
  printf("\n");

  /* 可変引数リスト終了 */
  va_end(ap);
}

va_list.c の実行結果は:

[cactus:~/code_c/refer]% ./va_list
I Can Do It !!

シグナル処理

signal.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*
  signal.h [signal]
  書式: void (*signal(int sig, void(*func)(int)))(int)
  機能: 指定シグナル番号を受信した際に指定関数の実行
  引数: int sig: シグナル番号
        void(*func)(int): 実行される関数
  戻り値: なし
*/

/*
  signal.h [raise]
  書式: int raise(int sig)
  機能: 指定シグナル番号のシグナルを送信
  引数: int sig: シグナル番号
  戻り値: なし
*/

#include <stdio.h>
#include <signal.h>

void func(int sig);

int main(void){

  signal(SIGABRT, func);
  raise(SIGABRT);
  
  return 0;
}

void func(int sig){
  printf("シグナル番号 %d を受信\n", sig);
}

signal.c の実行結果は:

[cactus:~/code_c/refer]% ./signal
シグナル番号 6 を受信

ジャンプ処理

setjmp.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/*
  setjmp.h [setjmp]
  書式: int setjmp(jmp_buf env)
  機能: ジャンプ処理用に現在の環境を待避する
  引数: jmp_buf env: 環境格納変数 ( longjmp() での指定用)
  戻り値: 最初に設定する際は, 0 を返し,
          longjmp() から呼ばれた場合は, 0 以外の
	  longjmp で指定された引数を返す.
*/

/*
  setjmp.h [longjmp]
  書式: void longjmp(jmp_buf env, int value)
  機能: 指定された位置にジャンプする
  引数: jmp_buf env: setjmp() で取得した環境格納変数
        int value: setjmp() の戻り値を設定
  戻り値: なし
*/

/*
  setjmp() と longjmp()
  を使用したジャンプ処理
  でループさせてみる
*/

#include <stdio.h>
#include <setjmp.h>

jmp_buf env;

int main(void){

  int i = 0;
  int ret = setjmp(env);

  if(ret == 0)
    printf("1 回目で始まり\n");
  else if( 0 < ret && ret < 8 )
    printf("longjmp() からジャンプしてきた [%d 回目]\n", i+1);
  else{
    printf("10 回目で終わり\n");
    return 0;
  }
  longjmp(env, i++);
}

setjmp.c の実行結果は:

[cactus:~/code_c/refer]% ./setjmp
1 回目で始まり
longjmp() からジャンプしてきた [2 回目]
longjmp() からジャンプしてきた [3 回目]
longjmp() からジャンプしてきた [4 回目]
longjmp() からジャンプしてきた [5 回目]
longjmp() からジャンプしてきた [6 回目]
longjmp() からジャンプしてきた [7 回目]
longjmp() からジャンプしてきた [8 回目]
longjmp() からジャンプしてきた [9 回目]
10 回目で終わり

入出力バッファリング設定

setbuf.txt

wtopia
C

setbuf.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/*
  入出力バッファリングの設定には, setbuf() と setvbuf()
  を使用する.
  バッファリングとは, 一時的にメモリ内に保存しておくことで,
  バッファリングすることで, 細切れのデータを 1 つに繋げて
  高速化できるなどのメリットがある.
*/

/*
  stdio.h [setbuf]
  書式: void setbuf(FILE *fp, char *buf)
  機能: 入出力バッファリングの設定
  引数: FILE *fp: ファイル (ストリーム) ポインタ
        char *buf: バッファの格納先
	NULL の場合は, バッファリングを実施しない.
	バッファの格納先サイズには, BUFSIZ が定義されている.
  戻り値: なし
*/

/*
  stdio.h [setvbuf]
  書式: int setvbuf(FILE *fp, char *buf, int mode, size_t size)
  機能: 入出力バッファリングの詳細設定
  引数: FILE *fp: ファイル (ストリーム) ポインタ
        char *buf: バッファの格納先 (NULL の場合は, バッファリング
	           を実施しない)
	int mode: バッファリングのモード
	size_t size: バッファの格納先サイズ
  戻り値: 成功すると, 0 を返し,
          失敗すると, 0 以外を返す.
*/

/*
  バッファリングのモード:
  _IOFBF: 完全なバッファリングを行う
  _IOLBF: 行単位でのバッファリングを行う
  _IONBF: バッファリングを行わない (バッファやバッファサイズ
          は無視される)
*/

#include <stdio.h>

int main(void){

  FILE *fp;
  char *fname = "setbuf.txt";
  char buf[BUFSIZ];
  int c;

  fp = fopen(fname, "r");
  if(fp == NULL){
    printf("%s ファイルが開けない\n", fname);
    return -1;
  }

  setbuf(fp, NULL);
  while( (c = fgetc(fp)) != EOF ){
    printf("%c", c);
  }

  rewind(fp);
  setbuf(fp, buf);

  while( (c = fgetc(fp)) != EOF ){
    printf("%c", c);
  }

  fclose(fp);

  return 0;
}

setbuf.c の実行結果は:

[cactus:~/code_c/refer]% ./setbuf
wtopia
C
wtopia
C

入出力バッファのフラッシュ

fflush.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
  stdio.h [fflush]
  書式: int fflush(FILE *fp)
  機能: 入出力バッファのフラッシュを行う
  引数: FILE *fp: ファイル (ストリーム) ポインタ
  戻り値: 成功すると, 0 を返し,
          失敗すると, EOF(-1) を返す.
*/

#include <stdio.h>

int main(void){

  char c;

  scanf("%c", &c);
  printf("1 文字目は: %c\n", c);

  fflush(stdin);

  scanf("%c", &c);
  printf("2 文字目は: %c\n", c);

  return 0;
}

fflush.c の実行結果は:

[cactus:~/code_c/refer]% ./fflush
w
1 文字目は: w
2 文字目は:

[cactus:~/code_c/refer]% ./fflush
wtopia
1 文字目は: w
2 文字目は: t