コミュニティアイコン プチコン 非公式コミュニティ トピック

アバター
しょうご ◆tpp2zBc4h8pI
2018/4/22 21:15
質問
文字列変数
複数の文字列変数をひとつの文字列変数にまとめて保存し、読み込みを行った際に再び文字列変数を複数にするにはどうすればよいのでしょうか?

コメント

アバター
TERA(LL) 2018/4/23 7:09 ◆qZ/8dOT.xLxY
>はるさん

私の使ってるプチコン3号SMILE BASICでは

LOCATE X,Y
PRINT A$,B$,C$

PRINT A$+B$+C$

の様に"," "+"を使ってもエラーにはなりませんが、はるさんは一体何の言語の事をコメントしてますか?
アバター
SAKURAmoti 2018/4/23 7:36 ◆wfyU/bSfcAH6
TERA(LL)さん
PRINT文は少し特殊なんですよー。
A$=B$,C$はエラーです。
はるさん
+はエラーなんですか!?
?ASC(CHR$(A$+B$)+1)
とかでもエラー出ませんが。
C#などでもエラーにはなりませんけど。
勘違いしてたらすみません。
アバター
はる 2018/4/23 8:30 ◆75Vh4SY8TdKS
TERA(LL)さん

","や"+"はエラーになりませんよ。
貴方こそなんのことをコメントしているんですか?
ここは、"プチコン 非公式コミュニティ"です。
プチコン以外の言語のことをいきなり話したりはしません。


SAKURAmotiさん

"+"はエラーにはなりません。
自分が知っている"+"でエラーになるのは、
PHPで文字列を"+"で繋ごうとしたときくらいです。
ちなみに、PHPでは文字列を出すときは"."を使います。
多分勘違いしていると思います。
アバター
たんじぇ 2018/4/23 14:47 ◆WDmFkVwZ4yMl
複数の文字列も1つにまとめようとしている文字列もどっちも文字列なので、単純に文字列連結しちゃうと複数の文字列に戻すときに、どこが複数の文字列の区切りか分からないので戻せない、ってのが今回のメインテーマ。

(目的は SAVE "TXT:MEMOFILE",TX$ で変数を1つにまとめないといけないからかも?)

じゃあどこが複数の文字列の区切りかが分かるように何か別の1文字をいれればいいというのがみんなが言っている「セパレート文字」(区切り文字)というもの。

たとえば
A$="なまえ" '主人公のなまえ
B$="240" ' HP
C$="25" 'MP
などあった場合、単純に連結したら "なまえ24025" となってしまうので、
区切り文字を入れて "なまえ,240,25" という文字列を作ってしまえば "," で区切られてるところを元にしてもとの文字列にもどせるはず。

じゃあこの ","(カンマ) 入りの連結した文字列を元に戻す方法はどうするかとというと一般的な方法はこんな手順です。

1. 連結した文字列を INSTR で区切り文字(ここではカンマ)の位置を調べる、ただし区切り文字の位置がなければ終了
※INSTRは開始位置と文字列と検索文字列を渡して、検索文字列の位置を返す命令

2.開始位置から区切り文字までの文字列をMID$で取得して元の文字列変数へ代入する
※MID$は文字列と開始位置と文字数を渡して切り出した文字列を返してくれる命令

3.開始位置を区切り文字位置の次の文字にして1.に戻る

区切り文字は必ずしもカンマではなくても、":" (コロン)や ";"(セミコロン)など、元の文字列で使わないものなら何でもOKなのです。

元の文字列がいろんな変数だと代入するときに Villit さんのコードのように、何番目の区切りのときはこの変数に代入と、ちょっと面倒なことをしないといけないので、将来的には配列変数に入れてしまって文字列連結の処理と変数への代入の処理を分けた方が何かと便利だったりします。
アバター
たんじぇ 2018/4/23 15:14 ◆WDmFkVwZ4yMl
さっきの配列にする場合は、
1.プログラムで使っているいろんな文字列変数を配列に代入する処理
2.配列を配列要素数分ループして1つの文字に連結する処理(必要ならそのままファイルに保存)
3.(必要ならファイルから読み出して)連結されている文字列を分割して配列に代入する処理
4.配列からプログラムで使っているいろんな文字列に代入する処理

の4つの処理ができて、変数が増えても2と3の文字列連結の処理は修正しなくてもよくなったりしますし、区切り文字を使う方法以外の処理を試す場合でも2と3の処理を修正するだけでよくなります。
そして2と3の処理は他のプログラムでも使い回せるようになったりします。


区切り文字を使う方法以外には、文字の長さを固定にするというのもあって、さっきの例の場合 A$もB$もC$も絶対8文字しかないと分かっているなら INSTRで区切り文字を検索しなくても MID$で8文字ごとに切り出すという簡単な方法もあります。
この場合は文字列連結するときにかならず8文字にしないといけないので連結するときに8文字未満なら空白で埋めたり、元の変数に戻すときに空白を削ったりしないといけないです。
(SUBST$で8文字空白の文字列を置換するとか、FORMAT$("% 8D",変数)で数値を空白あり文字列にするなど工夫は必要)


他にもいろんな方法がありますがやりかたの紹介だけしておきます。
(どれもプチコンだと面倒なのと使う場所が限られるけど、文字列じゃなくてバイナリにすれば画像ファイルの中身はだいたいこれと同じ仕組みです)

・連結文字列は区切り文字を使わず連結して、文字数を別の配列覚えておき、配列数、文字数用の配列、連結文字列を保存する方法
※さっきの例だと 3,[3,3,2],"なまえ24025" となるけど数値、配列、文字列がセットになるのでプチコンだと保存は簡単にできない

・区切り文字の代わりに固定の長さ(2文字くらい)で文字数をいれておいて、文字数分だけ読み出して変数へ代入し、さらに文字数があれば続ける
※さっきの例だと"03なまえ032400225"で、03 で3文字の"なまえ"で次の "03"で "240"、次の"02"で"25"となる
※区切り文字を使えないくらいにいろんな文字を使うバイナリデータの場合に有効
アバター
でんぺん 2018/4/23 16:04 ◆HfSy5ayxtyTa
A$=B$,C$
の代入でのカンマはエラーですね。代入で,で繋げることは出来ないので。PRINTは特殊で,で繋げて表示に命令に送る事が出来るので表示出来ます。

質問者の保存という言葉からもなんとなくセーブやロードで命令が文字か配列の1つだけなので、まとめたいのかなという印象ですね。

文字の連結は単純に+でやるのが簡単だと思うし区切り文字を挟むのも単に区切り文字を間にいれて+するだけだから問題ないと思うんですが、読み込んだ後の分割がちょっと面倒でやり方もいろいろあります。また固定長文字列(文字の長さが決まっている)なら区切りはいらないですし、たんじぇさんの言われているように先頭に文字の長さを入れる方法もあります。この先頭に文字の長さをいれる方法は文字での保存より配列(バイナリ)の方がより便利ですね。

とりあえず僕だったらINSTRとMID$を利用して文字を切り出して一旦文字配列に保存しておいて、その後、そこから他の変数に移すなりして利用する感じかなって思います。
アバター
しんいち 2018/4/23 17:21 ◆lHy.hAWXbthn
面白そうだったので文字列を分割する関数を作ってみました。
文字列配列で返します。区切り文字は複数種類でもOKで、元文字列中で区切り文字が連続していても1つの区切りとして扱います。
参考にどうぞ。
アバター
しょうご 2018/4/23 17:58 ◆tpp2zBc4h8pI
いつのまにかこんなにコメントが…。全てのコメントに目を通しましたが、単純なことでも、なかなか複雑なプログラムになるのですね。まずは文字を分けて、コメントで頂いたいくつかの方法を試してみたいと思います。皆さん、ありがとうございます。
アバター
moi 2018/4/23 18:01 ◆hL/XpFV8MD2F
DATA文では+(TAS)はエラー吐くんだね
アバター
Villit 2018/4/23 18:19 ◆vHS9PZuQvtOx
あ、そういえば文字列定数に直接指定できない記号とかありましたね
めんどくさいんで区切り文字はちょっと変な記号使った方がいいかもです、よくわからん絵文字とか
アバター
でんぺん 2018/4/23 18:52 ◆HfSy5ayxtyTa
区切り文字の種類は一つ等、制約をつければプログラムはもっとシンプルになると思いますし、自分なりに作ってみるのが良いと思います。

そんな風にプログラムには色んな方法があるのが難しく面白いところじゃないかなって思います。とくにそれを面白く感じられるようになれば、プログラムをもっと楽しめるようになると思いますね。頑張ってください!
アバター
しょうご 2018/4/25 20:10 ◆tpp2zBc4h8pI
配列が苦手なので、かなり苦戦しています。セーブ方法は文字数がバラバラなので、テキストファイルで保存しようと思います。
アバター
でんぺん 2018/4/25 21:53 ◆HfSy5ayxtyTa
配列的なものはどの言語でもあるし重要な概念だと思うので、今は苦手かもしれませんが、この機会(文字列でのセーブ)に覚えるのがいいんじゃないかなって思いますよ。

一度わかってしまえば簡単なことでもありますしね。逆にわかってないときは難しく感じてしまうのがこの手のものって感じもありますし。

わからない事を説明するのは難しいとも思いますが、少しずつ質問して知識を増やして理解していければいいんじゃないかなって思います。
アバター
でんぺん 2018/4/25 22:04 ◆HfSy5ayxtyTa
配列は(プチコンの場合)同種の変数(数値や文字列)を一つの変数名でまとめて管理出来るので便利です。

よく変数を箱などに例えたりしますが、僕は配列は仕切りで区切られた箱に例えたりすることがあります。つまり例えば、
DIM M$[5]
と変数を宣言(用意)するとM$という名前の変数(箱)に仕切りが入っていて5つの入れる場所があるようなイメージです。
この場合、箱の名前(変数名)はM$になりますが、そのどの場所に入れるか指定する必要があって、それが要素番号(インデックス)になり、要素番号は0から始まるので5つに分けた場合は、0〜4になるんで、例えば箱の右から入れている感じだとしたら、一番右(0番目)、その次が1(番目)というようにしていして、好きな場所に入れるような感じです。

M$[0]="なまえ1"
M$[1]="なまえ2"

と書いても、わかるかわからないかは人によるところもあるので、意味がわからなかったら追加で質問してくれれば答えますし、僕以外にもっとわかりやすく(別の例で)説明してくれる人が現れるかもしれないので、とにかく書いてみるのがいいんじゃないかなって思います。場合によって箱みたいな例を出すよりもストレートに書いた方がわかりやすい人もいるかもですしね。

コメントを書く

  • こちらは「プチコン3号」「プチコンBIG」など、プチコンシリーズに関する話題を扱ったコミュニティです
  • プチコンシリーズにまったく関係ない書き込みはご遠慮下さい。削除の対象となります
  • こちらにはその他のゲームや雑談のコミュニティはなく、作る予定もありません (ひとりで管理できないため)。ごめんなさい
  • ユーザー登録なしで書き込みができます
  • 秘密の合い言葉は成りすましの防止 (トリップ機能)、書き込みの編集時の本人認証に使用します
  • 秘密の合い言葉に他人に推測されやすい言葉、他サービスと同じパスワードは入力しないでください。
  • 書き込むと、投稿時に入力したお名前と秘密の暗号が記憶され、ログイン状態になります

- WEB PATIO -