もう、とりあえず解決になっていますので、スルーしてくださってかまいません。
この機会にどうしても載せておきたかったので置いておきます。
多分、時間とともにスレごと流れて消えます。
これは、質問の問題について、昼に作っていたモジュールです。
擬似的に多次元文字列型配列変数を作成し、管理します。
このモジュールで作成した擬似文字列型配列変数は B = A のように簡単にコピーできて、
ファイルに保存しても構造が壊れません。改行もOKです
;_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
;
;「Mod_SuspStrArray」(※Mod_SuspectedStrArrayの略)
;
; 疑似文字列型配列変数管理モジュール
; 4次元まで確保可能
;
; by FunnyMaker
; 2013/2/9
;
;
; [存在意義]
;
; HSP標準の文字列型配列変数は別の変数に内容を丸ごとコピーしたりファイルに書き出したりするために面倒な処理が
; 必要である。特に、文字列型配列変数の内容を別変数に丸ごとコピーする"モジュール"は作れないはず(?)。
; (∵モジュールでパラメータとして受け取るところまでは完璧にいけるが、文字列型配列変数はdupやdupptr命令を
; 使っても要素0以降は認識されない(∵Null文字のせい?)から、せっかくモジュール内でコピーを作成しても、
; その内容を呼び出し元から指定された変数に返すことができない)
; そこで、テキストデータに区切り用の文字列を入れてそれを管理し、文字列型配列変数のような感覚で使用
; でき、かつ容易にコピーしたりファイルに保存したりできるようなデータを作成すれば大変便利であると思ったため、
; このモジュールを作った。
;
;
; [書式]
;
; ・<バッファの初期化(関数)>
;
; 変数名1 = Mod_SSA_Secure(P1,P2,文字列1)
;
; 変数名1 : 初期化したい変数の名前
; P1 : 確保するメモリサイズ
; P2 : 確保する次元数(1〜4)
; 文字列1 : 各次元の要素数をカンマ区切りで指定。(HSP標準で言う、「dim A,1,1,2,2」等の「1,1,2,2」の部分
; と同じ感覚)
;
; 例えば、
; Aを3次元配列で(0,0,0)〜(1,1,1)まで確保し、全体の合計で1000文字分のメモリを確保したいなら、
; A = Mod_SSA_Secure(1000,3,"2,2,2")
; とすればよい。
;
; P1にはほぼ意味がない。バッファのメモリサイズは気にしなくて良い。ぶっちゃけ、0を指定しても正しく
; 初期化できる
;
; エラーが発生した場合はstatの値が1になり、それ以外の場合は0になる。
;
;
; ・<バッファの情報の取得(命令)>
;
; Mod_SSA_GetInfo 変数名1
;
; 変数名1 : 調べたい変数の名前
;
; 結果は「result@N_M_SSA2」整数型配列変数に保存される。各要素の内容は以下の通り。
; (0) : 次元数
; (1) : 1次元目の要素数
; (2) : 2〃
; (3) : 3〃
; (4) : 4〃
;
; エラーが発生した場合はstatの値が1になり、それ以外の場合は0になる。
;
; ・<バッファへの文字列の格納(関数)>
;
; 変数名1 = Mod_SSA_House(変数名1 , 文字列1 , 文字列2)
;
; 変数名1 : 代入先の変数の名前。2つ書かれているが、書き間違いではない。
; 文字列1 : 代入先のアドレスをカンマ区切りで指定。(HSP標準で言う、「A(0,0,2,1) = 3」等の「0,0,2,1」の部分
; と同じ感覚)
; 文字列2 : 格納する文字列
;
; 例えば、
; 3次元で(0,0,0)〜(1,1,1)まで確保したAの、(1,0,0)に「あいうえお」を格納したいならば
; A = Mod_SSA_House(A,"1,1,0","あいうえお")
; とすればよい。
;
; このモジュール実行後のstatの値とその意味
; 0 : 異常なし
; 1 : 格納する文字列に不正な文字列が含まれている。(「/{1}/」等。詳しくは[制約]を参照。)
; 2 : その他
; 尚、エラーが発生しても元のバッファが壊れることはない。
;
;
; ・<バッファからの読み出し(関数)>
;
; val = Mod_SSA_Read(変数名1,文字列1)
;
; 変数名1 : 読み出し元の変数の名前
; 文字列1 : 読み出し先のアドレスをカンマ区切りで指定(「Mod_SSA_House」命令のアドレス指定と同じ要領。)
;
; 例えば、
; 3次元で(0,0,0)〜(1,1,1)まで確保したAの、(1,0,0)にある文字列をmes命令で画面に表示したいなら、
; mes Mod_SSA_Read(A,"1,0,0")
; とすればよい。
;
; エラーが発生した場合はstatの値が1になり、それ以外の場合は0になる。
;
;
; [Q&A ヘルプ]
;
; Q >このモジュールで初期化した変数Aの内容を変数Bにそっくりそのままコピーしたいが、どうすればよいか?
;
; A > 数値データの時と同様に、「B = A」とすればよい。これで完璧にコピーできる。
; このモジュールで初期化したAも所詮普通の文字列データだから。
;
; Q >このモジュールで変数Aを初期化したが、もう用済みになった。普通の変数として使いたいのだが、
; A = 0やA = ""などとしてよいか?
;
; A >大丈夫。全く問題ない。このモジュールで初期化したAも所詮普通の文字列データだから。
;
; Q >このモジュールで初期化した変数に割り当てられているメモリサイズを拡張したいのだが、どうすれば
; よいか?
;
; A >memexpand命令を使うと良い。ただし、本モジュールの特性上、本モジュールで変数を操作する度に
; その変数のサイズは内部の文字列ギリギリのサイズにフィットされてしまうので、あまり意味はない。
;
; Q >このモジュールで初期化されている変数Aのメモリ使用サイズを知りたいのだが、どうすればよいか?
;
; A >現時点でスマートな方法はない。memfileでAをストリームに指定してからexistでその仮想ファイルのサイズ
; を調べる方法がある。
;
; Q >このモジュールで初期化した変数Aの内容を一旦ファイルに書き出して別の変数にリロードした。正しく使えるか?
;
; A >もちろん。これはそのためのモジュールだ。
;
;
; [制約]
;
; ・次元数を変更するときは初期化するしかない。
;
; ・同じ次元数でしか読み書きできない。例えば、4次元配列を3次元配列として読もうとしてもこのモジュールはそれを
; ブロックする。
;
; ・このモジュールを使う際に、次の各行に示す文字列と完全に一致する文字列を含む文字列は使ってはならない。
; /{1}/
; /{2}/
; /{3}/
; /{4}/
; これらは区切り用文字列として使われている。
;
; ・要素数の拡張はできない。例えばAを(0,0,0)〜(1,1,1)まで確保した場合、(0,0,2)は存在しないから、そこには
; 文字列を格納できない。
;
;
; [仕組み]
;
; ある変数Aを初期化するとして話をする。
;
; Aは文字列型変数で初期化される。
; Aの1行目には次元数を表す数字が1〜4で書き込まれる。例えば「3」と書き込まれている場合はAは3次元配列である。
; Aの2行目以降にメインデータが格納される。メインデータには改行が含まれている可能性がある。
; 一般に、このモジュールで初期化するバッファの2行目以降の文字列をαとする。
; αについて話をする。
;
; 第1次元目の配列要素数をk、
; 第2次元目の配列要素数をl
; 第3次元目の配列要素数をm
; 第4次元目の配列要素数をn
; とする。
; 第n次元目の区切り文字列は「/{n}/」である。
; この時、αの中には「/{1}/」がlimit{(k-1),0,(k-1)}個、「/{2}/」がk*limit{(l-1),0,(l-1)}個、「/{3}/」がk*l*limit{(m-1),0,(m-1)}個、「/{4}/」がk*l*m*limit{(n-1),0,(n-1)}個ある。
; Aが「/{1}/」でlimit{k,1,k}個に区切られ、それらおのおのが「/{2}/」でlimit{l,1,l)個に区切られ、・・・・・・というようになっている。
;
; 例えば、Aを3次元配列で(0,0,0)〜(1,1,1)まで確保した直後のαは下のようになっている
; A = /{3}//{3}//{2}//{3}//{3}//{2}//{3}//{3}//{1}//{3}//{3}//{2}//{3}//{3}//{2}//{3}//{3}//{1}//{3}//{3}//{2}//{3}//{3}//{2}//{3}//{3}/
;
; これを生成するアルゴリズムの、ある場合における動作例を下に示す。
;
; Aを3次元配列で(0,0,0)〜(k,l,m)まで確保する場合は以下のようになる。
; ただし、(k,l,m)=(2,2,2)
;
; [1]
; α=""
; [2]
; αに/{3}/を付け足す
; α = /{3}/
; αをm+1(=3)連する
; α = /{3}//{3}//{3}/
; 最後の/{3}/を取り除く
; α = /{3}//{3}/
; [3]
; αに/{2}/を付け足す
; α = /{3}//{3}//{2}/
; αをl+1(=3)連する
; α = /{3}//{3}//{2}//{3}//{3}//{2}//{3}//{3}//{2}/
; 最後の/{2}/を取り除く
; α = /{3}//{3}//{2}//{3}//{3}//{2}//{3}//{3}/
; [4]
; αに/{1}/を付け足す
; α = /{3}//{3}//{2}//{3}//{3}//{2}//{3}//{3}//{1}/
; αをk+1(=3)連する
; α = /{3}//{3}//{2}//{3}//{3}//{2}//{3}//{3}//{1}//{3}//{3}//{2}//{3}//{3}//{2}//{3}//{3}//{1}//{3}//{3}//{2}//{3}//{3}//{2}//{3}//{3}//{1}/
; 最後の/{1}/を取り除く
; α = /{3}//{3}//{2}//{3}//{3}//{2}//{3}//{3}//{1}//{3}//{3}//{2}//{3}//{3}//{2}//{3}//{3}//{1}//{3}//{3}//{2}//{3}//{3}//{2}//{3}//{3}/
;
;
; [コードの特性]
;
; Tabで1段下げてコメントアウトしているコードはデバッグ用。
; 苦戦した跡でもある。
;
;_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#module N_M_SSA1;「Name_Mod_SuspStrArray1」の略
;バッファの初期化
#defcfunc Mod_SSA_Secure int memsize , int dimensionality , str NOE_tmp
NOE = NOE_tmp
stat2 = 0
mref stat2,64
sdim NOE2,64,4
split NOE,",",NOE2
num1 = stat
;適性検査
if memsize < 0 : stat2 = 1 : return;メモリサイズ
if (dimensionality < 1)|(4 < dimensionality) : stat2 = 1 : return "";次元数
if num1 ! dimensionality : stat2 = 1 : return "";要素数
;dialog dimensionality
flag1 = 0
repeat dimensionality
;dialog cnt
if int(NOE2(cnt)) < 1 : flag1 = 1 : break
loop
if flag1 = 1 : stat2 = 1 : return "";要素数
sdim α,memsize : sdim buf1,memsize;メモリ確保
repeat dimensionality;区切り用文字列を書き込む
α += "/{"+str(dimensionality-cnt)+"}/"
letter1 = α
repeat int(NOE2(dimensionality-1-cnt)) - 1;連ねる
α += letter1
loop
α = strmid(α,0,strlen(α)-strlen("/{"+str(dimensionality-cnt)+"}/"));最後の余分な区切り文字列を消す
loop
notesel buf1
noteadd str(dimensionality)
noteadd α
stat2 = 0
return buf1
#global
#module N_M_SSA2
;バッファの情報の取得
#deffunc Mod_SSA_GetInfo str target_tmp
target = target_tmp
stat2 = 0
mref stat2,64
notesel target
noteget letter1,0 : dimensionality = int(letter1)
α = ""
repeat notemax - 1
noteget letter1,cnt+1
α = α + letter1 + "\n"
loop
α = strmid(α,0,strlen(α) - 2);末尾の余分な改行コードを消す
if (dimensionality < 1)|(dimensionality > 4) : stat2 = 1 : return;適性検査
result(0) = dimensionality;次元数
;<要素数の調査>
letter3 = α;一時データ初期化
repeat dimensionality;要素数を調べる。低次から順に調べる。
split letter3,"/{"+int(cnt+1)+"}/",letter2
result(cnt+1) = stat;要素数
letter3 = letter2(0);一時データ値更新
loop
stat2 = 0
return
#global
#module N_M_SSA3
;バッファへの文字列の格納
#defcfunc Mod_SSA_House str target_tmp , str address_tmp , str String_tmp
target = target_tmp
String = String_tmp
address = address_tmp
stat2 = 0
mref stat2,64
;<適性検査>
flag1 = 0
repeat 4
;dialog cnt
if instr(String,0,"/{"+str(cnt+1)+"}/") ! -1 : flag1 = 1 : break
loop
if flag1 = 1 : stat2 = 1 : return target;適性検査(格納する文字列内に区切り用文字列とバッティングするものがあるか?)
notesel target
noteget letter1,0 : dimensionality = int(letter1)
α = ""
repeat notemax - 1
noteget letter1,cnt+1
α = α + letter1 + "\n"
loop
α = strmid(α,0,strlen(α) - 2);末尾の余分な改行コードを消す
if (dimensionality < 1)|(4 < dimensionality) : stat2 = 1 : return target;適性検査(次元数)
Mod_SSA_GetInfo target;与えられたバッファの情報を取得
sdim NOE,64,4
split address,",",NOE
;<適性検査>
if stat ! dimensionality : stat2 = 2 : return target;アドレス
flag1 = 0
repeat dimensionality
if (int(NOE(cnt)) < 0)|(int(NOE(cnt)) > result@N_M_SSA2(cnt+1)-1) : flag1 = 1 : break
loop
if flag1 = 1 : stat2 = 2 : return target;アドレス
letter3 = α : index = 0;一時データ初期化。(letter3には最終的に、指定されたアドレスにある文字列が入る。indexには最終的に、指定されたアドレスにある文字列の左端の、α内でのオフセットが入る。)
repeat dimensionality
count1 = cnt
split letter3,"/{"+int(cnt+1)+"}/",letter2
;<一時データ更新>
letter3 = letter2(int(NOE(cnt)))
repeat int(NOE(cnt))
index = index + strlen(letter2(cnt)) + strlen("/{"+count1+"}/")
loop
loop
buf = strmid(α,0,index) + String + strmid(α,-1,strlen(α)-index-strlen(letter3));バッファの再構築
;dialog buf
notesel buf
noteadd str(dimensionality),0,0
stat2 = 0
return buf
#global
#module N_M_SSA4
;バッファからの文字列の読み出し
#defcfunc Mod_SSA_Read str target_tmp , str address_tmp
target = target_tmp
address = address_tmp
stat2 = 0
mref stat2,64
notesel target
noteget letter1,0 : dimensionality = int(letter1)
α = ""
repeat notemax - 1
noteget letter1,cnt+1
α = α + letter1 + "\n"
loop
α = strmid(α,0,strlen(α) - 2);末尾の余分な改行コードを消す
if (dimensionality < 1)|(4 < dimensionality) : stat2 = 1 : return "";適性検査(次元数)
Mod_SSA_GetInfo target;与えられたバッファの情報を取得
sdim NOE,64,4
split address,",",NOE
;<適性検査>
if stat ! dimensionality : stat2 = 1 : return "";アドレス
flag1 = 0
repeat dimensionality
if (int(NOE(cnt)) < 0)|(int(NOE(cnt)) > result@N_M_SSA2(cnt+1)-1) : flag1 = 1 : break
loop
if flag1 = 1 : stat2 = 1 : return "";アドレス
letter3 = α;一時データ初期化。(letter3には最終的に、指定されたアドレスにある文字列が入る。)
repeat dimensionality
split letter3,"/{"+str(cnt+1)+"}/",letter2
letter3 = letter2(int(NOE(cnt)));一時データ更新
loop
stat2 = 0
return letter3
#global
下はサンプルです。
#include "Mod_SuspStrArray.as"
mesb1 = ""
screen 0,800,600,0
font msgothic,25,1
pos 5,510 : mes "※実際にはこれよりもとても高速で動作します。\n あえて低速にしています。"
sysfont 17
objmode 1,1
pos 0,0
mesbox mesb1,800,500,4,0
wait 50
mesb1 += "Aを3次元配列で(0,0,0)から(1,1,1)まで確保"
objprm 0,mesb1
A = Mod_SSA_Secure(1000,3,"2,2,2")
wait 50
if stat = 0 {
notesel A
noteget α,1
mesb1 += "\n成功\nα = "+α+""
objprm 0,mesb1
} else {
mesb1 += "\n失敗\n終了します。"
objprm 0,mesb1
wait 100
end
}
wait 50
mesb1 += "\nAの情報を取得します"
objprm 0,mesb1
Mod_SSA_GetInfo A
wait 50
if stat = 0 {
mesb1 += "\n成功"
mesb1 += "\n次元数 = "+result@N_M_SSA2(0)+""
repeat result@N_M_SSA2(0)
mesb1 += "\n"+int(cnt+1)+"次元要素数 = "+result@N_M_SSA2(1+cnt)+""
loop
objprm 0,mesb1
} else {
mesb1 += "\n失敗\n終了します。"
objprm 0,mesb1
wait 100
end
}
wait 50
mesb1 += "\nAへの代入を開始します"
objprm 0,mesb1
wait 50
mesb1 += "\nA(0,0,0) = 俺"
objprm 0,mesb1
A = Mod_SSA_House(A,"0,0,0","俺")
wait 10
notesel A
noteget α,1
mesb1 += "\nα = "+α+""
objprm 0,mesb1
wait 10
mesb1 += "\nA(0,0,1) = だ"
objprm 0,mesb1
A = Mod_SSA_House(A,"0,0,1","だ")
wait 10
notesel A
noteget α,1
mesb1 += "\nα = "+α+""
objprm 0,mesb1
wait 10
mesb1 += "\nA(0,1,0) = け"
objprm 0,mesb1
A = Mod_SSA_House(A,"0,1,0","け")
wait 10
notesel A
noteget α,1
mesb1 += "\nα = "+α+""
objprm 0,mesb1
wait 10
mesb1 += "\nA(0,1,1) = 1"
objprm 0,mesb1
A = Mod_SSA_House(A,"0,1,1","1")
wait 10
notesel A
noteget α,1
mesb1 += "\nα = "+α+""
objprm 0,mesb1
wait 10
mesb1 += "\nA(1,0,0) = 日"
objprm 0,mesb1
A = Mod_SSA_House(A,"1,0,0","日")
wait 10
notesel A
noteget α,1
mesb1 += "\nα = "+α+""
objprm 0,mesb1
wait 10
mesb1 += "\nA(1,0,1) = 48"
objprm 0,mesb1
A = Mod_SSA_House(A,"1,0,1","48")
wait 10
notesel A
noteget α,1
mesb1 += "\nα = "+α+""
objprm 0,mesb1
wait 10
mesb1 += "\nA(1,1,0) = 時間"
objprm 0,mesb1
A = Mod_SSA_House(A,"1,1,0","時間")
wait 10
notesel A
noteget α,1
mesb1 += "\nα = "+α+""
objprm 0,mesb1
wait 10
mesb1 += "\nA(1,1,1) = 欲しい"
objprm 0,mesb1
A = Mod_SSA_House(A,"1,1,1","欲しい")
wait 10
notesel A
noteget α,1
mesb1 += "\nα = "+α+""
objprm 0,mesb1
wait 50
mesb1 += "\nAからの読み出しを開始します"
objprm 0,mesb1
wait 50
mesb1 += "\nA(0,0,0)+A(0,0,1)+A(0,1,0)+A(0,1,1)+A(1,0,0)+A(1,0,1)+A(1,1,1) = "+Mod_SSA_Read(A,"0,0,0")+""+Mod_SSA_Read(A,"0,0,1")+""+Mod_SSA_Read(A,"0,1,0")+""+Mod_SSA_Read(A,"0,1,1")+""+Mod_SSA_Read(A,"1,0,0")+""+Mod_SSA_Read(A,"1,0,1")+""+Mod_SSA_Read(A,"1,1,0")+""+Mod_SSA_Read(A,"1,1,1")+""
objprm 0,mesb1
wait 100
mesb1 += "\nAの内容をBにコピーします\nB = A"
objprm 0,mesb1
B = A
wait 50
mesb1 += "\nBからの読み出しを開始します"
objprm 0,mesb1
wait 50
mesb1 += "\nB(0,0,0)+B(0,0,1)+B(0,1,0)+B(0,1,1)+B(1,0,0)+B(1,0,1)+B(1,1,1) = "+Mod_SSA_Read(B,"0,0,0")+""+Mod_SSA_Read(B,"0,0,1")+""+Mod_SSA_Read(B,"0,1,0")+""+Mod_SSA_Read(B,"0,1,1")+""+Mod_SSA_Read(B,"1,0,0")+""+Mod_SSA_Read(B,"1,0,1")+""+Mod_SSA_Read(B,"1,1,0")+""+Mod_SSA_Read(B,"1,1,1")+""
objprm 0,mesb1
もういっちょ。
#include "Mod_SuspStrArray.as"
A = Mod_SSA_Secure(64,3,"2,2,2")
A = Mod_SSA_House(A,"0,0,0","こんにちは。\n元気ですか?\n")
A = Mod_SSA_House(A,"0,0,1","ええ、元気です。\nまあ、ちょっと風邪を引いてますがね。\n")
A = Mod_SSA_House(A,"0,1,0","そうですか。\n大事になさってくださいよ。\n")
A = Mod_SSA_House(A,"0,1,1","はい、大丈夫です。\nこんな風邪、すぐ治りますよ。\n")
mes Mod_SSA_Read(A,"0,0,0")
mes Mod_SSA_Read(A,"0,0,1")
mes Mod_SSA_Read(A,"0,1,0")
mes Mod_SSA_Read(A,"0,1,1")
mes "↓バッファの内容"
mes A
color 255,0,0 : line 0,200,639,200