『Cプログラミング診断室』目次次(第7章 文字処理は得意 改造)

第7章 文字処理は得意

メッセージ


漢字のメッセージを出すためのデータが、ヘッダーファイル"kanji.h"(リスト7−1)に書か れています。それぞれのメッセージは、マクロ定義されています。奇妙なのは、本当のメッセージ の前に、訳の分からない余分なものがついていることでしょう。(\dは文字定数の10進数表記を示 しています。これはふつうのCにはない仕様ですが、そのままにしておきます。)

 
リスト7−1 ヘッダファイル(漢字メッセージの定義)

     1	/******************************************************************************
     2	*
     3	*         Definition of Kanji message for Command Make program
     4	*
     5	*/
     6	
     7	#ifndef _KANJI_H
     8	#define _KANJI_H
     9	
    10	#define   M140 "\d074\d018■MOD"
    11	#define   M150 "\d043\d018■中止"
    12	#define   M160 "\d050\d018■実行"
    13	#define   M170 "\d057\d018■印字"
    14	#define   M180 "\d064\d018■次へ"
    15	#define   M190 "\d043\d018■中断"
    16	#define   M192 "\d071\d018■設定"
    17	#define   M194 "\d071\d018■全削除"
    18	
    19	#define   M200 "\d040\d001子局名選択"
    20	#define   M210 "\d040\d001制御項目選択"
    21	#define   M220 "\d040\d001受信中"
    22	#define   M222 "\d040\d001受信できませんでした。"
    23	#define   M224 "\d040\d001ステーション・エラーが生じました。"
    24	#define   M226 "\d040\d001ライン・エラーが生じました。"
    25	
    26	#define   M692 "\d045\d003運用開始"
    27	#define   M694 "\d045\d004運用終了"
    28	
    29	#define   M720 "運用時間"
    30	#define   M730 "運用時間設定"
    31	
    32	#define   M900 "\d065\d003●0"
    33	#define   M910 "\d065\d004●1"
    34	#define   M920 "\d065\d005●2"
    35	#define   M930 "\d065\d006●3"
    36	#define   M940 "\d065\d007●4"
    37	#define   M950 "\d065\d008●5"
    38	#define   M960 "\d065\d009●6"
    39	#define   M970 "\d065\d010●7"
    40	#define   M980 "\d065\d011●8"
    41	#define   M990 "\d065\d012●9"
    42	
    43	#endif _KANJI_H

 
リスト7−2 漢字メッセージの表示関数

     1	/******************************************************************************
     2	*
     3	*       Command Make program
     4	*
     5	*/
     6	
     7	#include "mydefs.h"
     8	
     9	/******************************************************************************
    10	*
    11	*       Display of Message for light pen
    12	*
    13	*/
    14	DispMsg(msgcnt, msgptr)
    15	
    16	int     msgcnt;
    17	char    **msgptr;
    18	
    19	{
    20	int     x,y;
    21	char    *ptr;
    22	
    23	    for( ; msgcnt != ZERO; msgcnt--){
    24	        ptr = *msgptr;
    25	        x = *ptr++;
    26	        x -= W3XOFFSET;
    27	        y = *ptr++;
    28	        y -= W3YOFFSET;
    29	        locate(STDERR, x, y);
    30	        fprintf(wpath, "%s", ptr);
    31	        fflush(wpath);
    32	
    33	        msgptr++;
    34	    }
    35	}
    36	
    37	/******************************************************************************
    38	*
    39	*       Standerd data Display (jyushin chuu no hyouji, chuushi, inji, tsugie)
    40	*
    41	*/
    42	StandDsp(timeup)
    43	
    44	int     timeup;                         /* time until time up           */
    45	
    46	{
    47	char    *msgptr[3];                     /* message pointer arry         */
    48	int     msgcnt;                         /* message count                */
    49	int     msgnum;                         /* message number               */
    50	
    51	int     d3_cnt;                         /* d3_ data count               */
    52	int     d3_offset;                      /* d3_ structure offset         */
    53	int     dspline;                        /* display line                 */
    54	int     dspend;                         /* display end flag             */
    55	int     getd3data;                      /* get d3 data count            */
    56	int     timecnt;                        /* time counter for operater    */
    57	int     value;                          /* return value                 */
    58	
    59	
    60	    cls2();
    61	    msgcnt = 1;
    62	    msgptr[0] = M220;
    63	    DispMsg(msgcnt, msgptr);
    64	
    65	    /* receive of ressponce data    */
    66	    value = Receive(timeup);
    67	    if(value == TIMEUP){
    68	        cls2();
    69	        msgcnt = 1;
    70	        msgptr[0] = M222;
    71	        DispMsg(msgcnt, msgptr);
    72	        tsleep(3 * TPS);
    73	        return(RETURN);
    74	    }else{
    75	        if(value == STD_ERROR){
    76	            switch(TdRpt.tr_lineno.str2[1]){
    77	                case CE_STATERR:
    78	                    cls2();
    79	                    msgcnt = 1;
    80	                    msgptr[0] = M224;
    81	                    DispMsg(msgcnt, msgptr);
    82	                    break;
    83	                case CE_LINEERR:
    84	                    cls2();
    85	                    msgcnt = 1;
    86	                    msgptr[0] = M226;
    87	                    DispMsg(msgcnt, msgptr);
    88	                    break;
    89	                default:
    90	                    break;
    91	            }
    92	            tsleep(3 * TPS);
    93	            return(RETURN);
    94	        }else{
    95	            /* standerd data    */
    96	        }
    97	    }
    98	
    99	    /* hyouji               */
   100	    d3_cnt = d3expand(d3_count);
   101	    d3_offset = ZERO;
   102	
   103	    dspend = TRUE;
   104	    do{
   105	        cls2();
   106	        locate(STDERR, DSPLINEX - W3XOFFSET, DSPLINEY - W3YOFFSET);
   107	        if(d3_cnt <= DSPLINECNT){
   108	            dspline = d3_cnt;
   109	            getd3data = d3disp(wpath, d3_offset, dspline, OFF);
   110	            dspend = FALSE;
   111	        }else{
   112	            dspline = d3_cnt;
   113	            getd3data = d3disp(wpath, d3_offset, dspline, OFF);
   114	        }
   115	
   116	        msgcnt = 3;
   117	        msgptr[0] = M150;
   118	        msgptr[1] = M170;
   119	        msgptr[2] = M180;
   120	        DispMsg(msgcnt, msgptr);
   121	
   122	        msgnum = ReadLPen(msgcnt, msgptr, 60 * 1);
   123	        if(msgnum == TIMEUP){
   124	            goto Jump2;
   125	        }
   126	        switch(msgnum){
   127	            case 1: /* chuushi      */
   128	                return(RETURN);
   129	            case 2: /* inji     */
   130	                if(PaperChk() == ON){
   131	                    (PaperChk() == ON)? putc(CR, ppath): NULL;
   132	                    d3disp(ppath, d3_offset, dspline, ON);
   133	                    (PaperChk() == ON)? putc(CR, ppath): NULL;
   134	                }
   135	            case 3: /* tsugie       */
   136	Jump2:
   137	                d3_offset += getd3data;
   138	                d3_cnt -= getd3data;
   139	                if(d3_cnt == ZERO){
   140	                    dspend = FALSE;
   141	                }
   142	                break;
   143	            default:
   144	                break;
   145	        }
   146	
   147	    }while(dspend);
   148	
   149	    return(CONTINUE);
   150	}

この変なメッセージを処理するための関数が、リスト7−2の最初の関数DispMsgです。この関 数は、メッセージの個数と配列を与えると、複数のメッセージを表示します。msgptrはchar**型で、 メッセージ(文字列)へのポインタの配列です。 msgptrから、forループの度に、メッセージへの ポインタをptrに入れています。ここまでは、普通です。

次に、ポインタの指す内容からW3XOFFSETを引いたものをx、次の内容からW3YOFFSETを引いたも のをyにしています。そして、その次にlocate関数があるので、このx,yがカーソル位置だったこと が分かります。

つまり、メッセージの最初の2バイトは、表示位置でした。表示位置は0もあり、そのままでは 文字列が終わってしまうと思い込み、適当な値 (W3XOFFSET,W3YOFFSET)を加えていたのでした。こ れで、変なメッセージの書き方の謎は解けました。

ここで読者に紹介しているのは、元の漢字メッセージファイル中から、今回ご覧いただくファイ ルに直接関係する辺りだけです。実際のファイルには、このような#defineが200行以上並んでいま す。それも、マクロ名がみんな、M140という調子で、たぶんメッセージを意味するMの後に、メッ セージ番号をつけただけなのでしょう。このような名前の付け方もいやなものです。M720とM730の 2 つだけは、先頭に位置データがありません。実際にこのデータを使用する関数(リストは省略) を調べてみると、これらのデータにも先頭に位置データが必要なことが分かりました。先頭に変な 方法で位置データを入れたりするため、忘れてしまったのでしょう。「運」の字の文字コードから 位置を決めたら、いったいどこに表示されるのでしょうね。

このメッセージ表示関数の呼出しは、リスト7−2の関数StandDsp中に何カ所もあります。1行 だけの表示は、61〜63行にあり、

    msgcnt = 1;
    msgptr[0] = M220;
    DispMsg(msgcnt,msgptr);
となっています。複数行にわたって表示する例は、 116〜120行にあり、
    msgcnt = 3;
    msgptr[0] = M150;
    msgptr[1] = M170;
    msgptr[2] = M180;
    DispMsg(msgcnt,msgptr);
となっています。多くのメッセージ表示が1行のみであることから、DispMsgの仕様を1つのメッ セージだけを表示することにすると、以上の部分は、
    DispMsg(M220);
    DispMsg(M150);
    DispMsg(M170);
    DispMsg(M180);
だけで済みます。こうすると、1行の場合は非常に単純になりますね。DispMsgをデータ1個のみ、 最後にsをつけたDispMsgsをデータn個の表示用にすると良いでしょう。もちろん、DispMsgsの実 現にはDispMsgを使います。

以上のメッセージ表示関数を利用した実際の処理の一部がリスト7−3です。Job2という関数で、 「運用時間の登録抹消」という処理をしているようです。

ところで91,101行に、

    ptr += 2;
があります。突然こんな式が出てくると、「何だろう?」と悩みの種になります。直前で、ptrに はメッセージデータの先頭アドレスを代入しているので、+=2 で位置データの2バイト分をスキッ プしていることが分かります。でも、メッセージ部分を指定するのに、わざわざ2加えるなんて細 工はしたくないものです。

 
リスト7−3 Job Process

     1	/******************************************************************************
     2	*
     3	*       *** CmdMake_DTS ***
     4	*
     5	*       Job process of Command Make program
     6	*
     7	*/
     8	
     9	#include "mydefs.h"
    10	
    11	#define UNYOU0PATH      "/D0/DATA/Unyou_0"
    12	#define UNYOU1PATH      "/D0/DATA/Unyou_1"
    13	
    14	/******************************************************************************
    15	*
    16	*       Job 2 (unnyou-jikan no touroku matsusyou)
    17	*
    18	*/
    19	Job2()
    20	{
    21	char    *msgptr[12];                    /* message pointer arry         */
    22	int     msgcnt;                         /* message counter              */
    23	int     msgnum;                         /* message number               */
    24	int     msgnum2;
    25	int     fpath;                          /* file path                    */
    26	int     offset;                         /* offset for unyou table       */
    27	int     x, y;
    28	
    29	char    *posptr[4];                     /* display postion pointer arry */
    30	int     lcount;                         /* loop counter                 */
    31	char    date[9];                        /* arry of yy,mm,dd,hh,mm       */
    32	char    **pptr;                         /* postion pointer              */
    33	char    *ptr;                           /* xy axis value pointer        */
    34	char    outbuf[40];                     /* buffer for output            */
    35	
    36	
    37	        /* unnyou jikoku no hyouji      */
    38	        cls();
    39	        msgcnt = 2;
    40	        msgptr[0] = M692;
    41	        msgptr[1] = M694;
    42	        DispMsg(msgcnt, msgptr);
    43	
    44	        /* UNYOU no hyouji              */
    45	        fpath = open((jobid==0)? UNYOU0PATH: UNYOU1PATH, S_IREAD);
    46	        if(fpath == ERROR) xexit(413);
    47	        lseek(fpath, 0L, 0);
    48	        if(read(fpath, &unyoutbl[0].t_year, sizeof(unyoutbl)) == ERROR) xexit(414);
    49	        close(fpath);
    50	
    51	        pptr = msgptr;
    52	        offset = 0;
    53	        while(offset != sizeof(unyoutbl) / sizeof(struct sgtbuf)){
    54	            ptr = *pptr++;
    55	            x = *ptr++;
    56	            x += KANJILEN * 4;
    57	            x -= W3XOFFSET;
    58	            y = *ptr;
    59	            y -= W3YOFFSET;
    60	            if(unyoutbl[offset].t_year == ON){
    61	                locate(STDERR, x, y);
    62	                fprintf(wpath, "  %02d:%02d",
    63	                                unyoutbl[offset].t_hour, unyoutbl[offset].t_minute);
    64	                fflush(wpath);
    65	            }
    66	            else{
    67	                locate(STDERR, x, y);
    68	                fprintf(wpath, "  00:00");
    69	                fflush(wpath);
    70	            }
    71	            offset++;
    72	        }
    73	   
    74	        msgcnt = 3;
    75	        msgptr[0] = M150;
    76	        msgptr[1] = M170;
    77	        msgptr[2] = M180;
    78	        DispMsg(msgcnt, msgptr);
    79	        msgnum = ReadLPen(msgcnt, msgptr, 60 * 1);
    80	        if(msgnum == TIMEUP){
    81	            return;
    82	        }
    83	        switch(msgnum){
    84	            case 1: /* chuushi      */
    85	                return;
    86	            case 2: /* inji         */
    87	                if(PaperChk() == ON){
    88	                    (PaperChk() == ON)? putc(CR, ppath): NULL;
    89	                    if(PaperChk() == ON){
    90	                        ptr = M692;
    91	                        ptr += 2;
    92	                        if(unyoutbl[0].t_year == ON){
    93	                            sprintf(outbuf,"  %s  %02d:%02d", 
    94	                                        ptr, unyoutbl[0].t_hour, unyoutbl[0].t_minute);
    95	                            fprintf(ppath, "%s\n", outbuf);
    96	                        }
    97	                        else{
    98	                            fprintf(ppath, "  %s  00:00\n", ptr);
    99	                        }
   100	                        ptr = M694;
   101	                        ptr += 2;
   102	                        if(unyoutbl[1].t_year == ON){
   103	                            sprintf(outbuf,"  %s  %02d:%02d", 
   104	                                        ptr, unyoutbl[1].t_hour, unyoutbl[1].t_minute);
   105	                            fprintf(ppath, "%s\n", outbuf);
   106	                            fflush(ppath);
   107	                        }
   108	                        else{
   109	                            fprintf(ppath, "  %s  00:00\n", ptr);
   110	                            fflush(ppath);
   111	                        }
   112	                    }
   113	                    (PaperChk() == ON)? putc(CR, ppath): NULL;
   114	                }
   115	            case 3: /* tsugie       */
   116	                break;
   117	            default:
   118	                break;
   119	       }
   120	
   121	Retry:
   122	        /* unnyou kaishi(hh,mm) to syuuriyou(hh,mm) no nyuuriyoku       */
   123	        cls();
   124	        msgcnt = 2;
   125	        msgptr[0] = M720;
   126	        msgptr[1] = M730;
   127	        DispMsg(msgcnt, msgptr);
   128	        msgcnt = sizeof(msgptr) / sizeof(char *);
   129	        msgptr[0] = M900;
   130	        msgptr[1] = M910;
   131	        msgptr[2] = M920;
   132	        msgptr[3] = M930;
   133	        msgptr[4] = M940;
   134	        msgptr[5] = M950;
   135	        msgptr[6] = M960;
   136	        msgptr[7] = M970;
   137	        msgptr[8] = M980;
   138	        msgptr[9] = M990;
   139	        msgptr[10] = M150;                      /* chuushi              */
   140	        msgptr[11] = M192;                      /* retry                */
   141	        DispMsg(msgcnt, msgptr);
   142	
   143	        posptr[0] = M720;
   144	        posptr[1] = M730;
   145	
   146	        lcount = 2;
   147	        msgnum2 = Select3(lcount, msgcnt, msgptr, posptr, date);
   148	        if(msgnum2 == msgcnt - 1){
   149	                return;
   150	        }else{
   151	                if(msgnum2 == msgcnt){
   152	                        goto Retry;
   153	                }
   154	        }
   155	
   156	        /* HH 10**1 */
   157	        outbuf[0] = date[2];
   158	        date[2] = NULL;
   159	        unyoutbl[0].t_hour = atoi(&date[0]);
   160	        date[2] = outbuf[0];
   161	        /* HH 10**0 */
   162	        outbuf[0] = date[4];
   163	        date[4] = NULL;
   164	        unyoutbl[0].t_minute = atoi(&date[2]);
   165	        date[4] = outbuf[0];
   166	        /* MM 10**1 */
   167	        outbuf[0] = date[6];
   168	        date[6] = NULL;
   169	        unyoutbl[1].t_hour = atoi(&date[4]);
   170	        date[6] = outbuf[0];
   171	        /* MM 10**0 */
   172	        date[8] = NULL;
   173	        unyoutbl[1].t_minute = atoi(&date[6]);
   174	
   175	        unyoutbl[0].t_year = ON;
   176	        unyoutbl[1].t_year = ON;
   177	Next2:
   178	        /* chuushi ka jitsukou          */
   179	        cls();
   180	        msgnum = Select2();
   181	        if(msgnum == STOP2) return;
   182	        UnyouIssue(FALSE);
   183	}


Copyright1996 Hirofumi Fujiwara. No reproduction or republication without written permission
『Cプログラミング診断室』目次次(第7章 文字処理は得意 改造)