†REXXのどろぬま†

文字列リストの処理

作成開始日 2015.06.10
最終更新日 2015.06.10

例えば、あるプログラムで複数のディレクトリ内のデータを一括処理する場合(検索とかバックアップとか形式変換とか)、処理対象のディレクトリ名をいちいち配列要素に代入していては何かと不便。
dir.1='c:\mydir'
dir.2='e:\mywork\today'
dir.3='d:\mydata\archive'
 ……
dir.8='g:\download\prog'
dir.0=8
そもそも記述が面倒だし、リストの順序変更や追加・削除の際には、添字に矛盾が生じないように細心の注意が必要。こうした煩雑さを解決する一番簡単な方法は、リストを外部データファイルにして、Do While〜で読み込むこと。これなら、リストの変更に柔軟に対応できる。たとえば;
c:\mydir
e:\mywork\today
d:\mydata\archive
 ……
g:\download\prog
のような中味のファイルdata.txtを;
inp='data.txt'
rc=STREAM(inp,'C','O');
n=0
Do While LINES(inp)>0
  n=n+1
  dir.n=LINEIN(inp)
End
dir.0=n
rc=STREAM(inp,'C','C');
のようなルーチンで読み込めばよい。この方法ならば、データの追加・削除にも簡単に対応できる。問題は、他プログラムと共有する訳でもないデータを、外部ファイルにすることに対する異和感。そこで、ほぼ同様なことを、プログラム内で実現してみた。
/* データの定義 */
data=,
'c:\mydir',
'e:\mywork\today',
'd:\mydata\archive',
 ……
'g:\download\prog',
;

/* データの配列への代入 */
n=0
Do While LENGTH(data)>0
  n=n+1
  PARSE VAR data item tmp
  dir.n=item
  data=tmp
End
dir.0=n
まず、データの定義部分だが、これは文法的には文字列を連結しているだけ。ただし、継続記号(,)を使用することで、1行1つの同一形式データになっている。また、この書式の場合、各データの末尾にはスペースが一つ追加される。つまり、上記の定義は、内容的には;
data='c:\mydir e:\mywork\today d:\mydata\archive …… g:\download\prog'
と同等である。ポイントは、それが1行1データ形式で記述できるため、追加・削除が極めて簡単だと言う点にある。もちろん、引用符と末尾カンマは必須だが、添え字に留意する必要は全くない(そういや、BASICにはDATA命令があったなぁ…)。で、その文字列データを、要素ごとに切り出しているのが次の処理ルーチン。頭から1データずつ切り取って配列に代入している。

なお、対のデータを処理する時も、リストを2本作るよりも、適当な記号で2つの要素をくっつけて、後で文字列処理するとよい。たとえば、ディレクトリ名とその用途を対で処理したければ、両者を「|」等で繋げたリストを作れば良い(「|」はファイル名/ディレクトリ名に使用不可能なので、ファイル名/ディレクトリ名中には絶対に出てこない…ハズ)。

data=,
'c:\mydir|ホームディレクトリ',
'e:\mywork\today|今日の仕事',
'd:\mydata\archive|当面使わないデータ',
 ……
'g:\download\prog|ネットで入手したプログラム',
;

n=0
Do While LENGTH(data)>0
  n=n+1
  PARSE VAR data item tmp
  p=POS('|',item)
  dir.n=LEFT(item,p-1)
  title.n=SUBSTR(item,p+1)
End
dir.0=n
title.0=n


【REXXのどろぬま目次】 【ホーム】