C言語-コマンドの作成
前へ 目次へ 次へ 

2-6 xtype

【名前】 xtype - 複数ファイルの内容を表示する。

【書式】 xtype [-npl#] filename1 [filename2 ...]

【解説】 指定された複数のファイルの内容を連続して表示する。次のオプションが使用できる。

-n : 行番号付きで表示する。
-p : 1画面表示ごとに一時停止する。
-l# : 先頭から#行だけ表示する。#省略時は、20行。
   オプションはコマンドとファイル名の間に指定する。

【参照】 mtype, num, page

 オプションの判定には、UNIXでは標準で用意されている関数getopt()を使用している。

リスト

16〜18行目:関数getopt()を使用するための宣言
24〜42行目:オプション文字の判定処理

 MS-DOS用のCコンパイラには、関数getopt()が用意されていないものもあるので、そのソースリストを後に示してある(ファイル名はgetopt.cとする)。利用する方法はいくつかある。

  1. ソースファイルxtype.cの中にgetopt.cを読み込んで1つのファイルにする。この場合、xtype.cの16〜18行の宣言は特に必要ない。コンパイルも通常と変わりない。
    > cc xtype.c
  2. ソースファイルxtype.cとgetopt.cを別々に用意する。コンパイルはファイル名を2つ指定する。
    > cc xtype.c getopt.c
    実行ファイル名は、最初に指定したxtype.exeになる。または、
    > cc -c getopt.c
    としてオブジェクトファイルgetopt.objを作成してき、次のようにコンパイルする。
    > cc xtype.c getopt.obj
 この他にも、関数getopt()をライブラリファイルに登録してしまう方法もある。システムごとに方法が違うのでマニュアル等を調べる必要がある。

 ファイルを1行読み込んで(51行目)から、各オプションにしたがって処理をしている。その部分については、num.cやpage.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:
#include <stdio.h>
#include <stdlib.h>

#define STRING_MAX 256  /* 最大文字長の定義 */
#define PAGE  22        /* 1画面分の行数 */
#define OPT_n 0x01      /* オプション判定用 */
#define OPT_p 0x02
#define OPT_l 0x04

int main(int argc, char **argv)
{
    FILE    *filep;
    char    buff[STRING_MAX];
    int     countn, countp = 0;
    int     opt = 0, optl = 20;
    extern int  getopt(int, char **, char *);   /* 関数getopt()の宣言 */
    extern int  opterr, optind, optopt;         /* getopt()で参照する */
    extern char     *optarg;

    if(argc < 2){                               /* パラメータ数のチェック */
        printf("Usage : XTYPE [-npl#] filename1 [filename2 ...]\n");
        exit(1);
    }
    opterr = 0;                                 /* getopt エラー非表示 */
    while(getopt(argc, argv, "npl:") != EOF){   /* オプション判定 */
        switch(optopt){
            case 'n':
                opt = opt | OPT_n;
                break;
            case 'p':
                opt = opt | OPT_p;
                break;
            case 'l':
                opt = opt | OPT_l;
                if(optarg != NULL)
                    optl = atoi(optarg);
                break;
            default:
                printf("unknown option -%c\n", optopt);
                exit(3);
        }
    }
    argc = argc - optind;
    argv = argv + optind;
    while(argc){                                  /* ファイル数分繰り返す */
        if((filep = fopen(*argv, "r")) == NULL){      /* オープンチェック */
            printf("can not open file. %s\n", *argv);
            exit(2);
        }
        countn = 0;                           /* 行数表示カウンタのクリア */
        while(fgets(buff, STRING_MAX, filep) != NULL){ /* 1行読み込み */
            ++countn;                                  /* 行数表示1行加算 */
            ++countp;                                  /* 一時停止1行加算 */
            if(opt & OPT_n)                            /* option n */
                printf("%6d ", countn);                /* 行数表示 */
            printf("%s", buff);                        /* 1行表示 */
            if(opt & OPT_p && countp == PAGE){         /* option p */
                countp = 0;
                printf("--- wait ---");
                gets(buff);
            }
            if(opt & OPT_l && countn == optl)          /* option l */
                break;
        }
        fclose(filep);                                /* クローズ */
        --argc;
        ++argv;
    }
    return(0);
}


 次に、参考として関数getopt()のリストを示す。UNIXでは、標準で用意されているので必要ない。MS-DOSの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:
/*LINTLIBRARY*/
/***********************************************************************
    getopt.c  このgetopt.cはPublic Domainです
    1996.4 Hiroshi Masuda 変更
***********************************************************************/
#include <stdio.h>
#include <string.h>

int     opterr = 1;       /* getopt()エラーメッセージ 1:表示 0:非表示 */
int     optind = 1;       /* getopt()インデックス */
int     optopt;           /* 取得オプション文字 */
char    *optarg;          /* 取得オプションパラメータ文字列 */

static void errdisp(char *cmd, char *as)
{
    static char     crtail[ ] = {0, '\n', 0};

    if(opterr){
        fputs(cmd, stderr);     fputs(as, stderr);
        *crtail = optopt;   fputs(crtail, stderr);
    }
}

int getopt(int ac, char **av, char *opts)
{
    static char     *curopt = NULL;
    register char   *cp;

    if(curopt == NULL || !*curopt){
        curopt = av[optind];
        if(optind >= ac || *curopt != '-' || !curopt[1])
            return(EOF);                 /* オプション指定なし */
        if(!strcmp("-", ++curopt)){
            ++optind;
            return(EOF);                 /* -- 指定 */
        }
    }
    optopt = *curopt++;                 /* option文字格納 */
    cp = strchr(opts, optopt);          /* option文字検索 */
    if(optopt == ':' || cp == NULL){    /* option文字不正 or 検索失敗 */
        errdisp(*av, ": unknown option, -");
        if(!*curopt)
            ++optind;
        return('?');
    }
    if(*++cp == ':'){                   /* optionパラメータあり */
        ++optind;
        if(*curopt){
            optarg = curopt;
            curopt = NULL;
        }else{
            if(optind >= ac){
                errdisp(*av, ": argument missing for -");
                return('?');
            }else{
                optarg = av[optind++];
            }
             /* now *curopt == '\0' */
        }
    }else{
        optarg = NULL;
        if(!*curopt) ++optind;
    }
    return(optopt);
}


前へ 目次へ 次へ 
Copyright © 2001 Hiroshi Masuda 

 

 

inserted by FC2 system