C言語-コマンドの作成 |
2-6 xtype
【名前】 xtype - 複数ファイルの内容を表示する。
【書式】 xtype [-npl#] filename1 [filename2 ...]
【解説】 指定された複数のファイルの内容を連続して表示する。次のオプションが使用できる。
-n : 行番号付きで表示する。
-p : 1画面表示ごとに一時停止する。
-l# : 先頭から#行だけ表示する。#省略時は、20行。
オプションはコマンドとファイル名の間に指定する。
【参照】 mtype, num, page
オプションの判定には、UNIXでは標準で用意されている関数getopt()を使用している。
リスト
MS-DOS用のCコンパイラには、関数getopt()が用意されていないものもあるので、そのソースリストを後に示してある(ファイル名はgetopt.cとする)。利用する方法はいくつかある。
ファイルを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 |