HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2009
0826
skyblue文字列入力21解決


skyblue

リンク

2009/8/26(Wed) 15:25:06|NO.27327

文字列(1b文字と2b文字、特に2b文字)を一文字ずつ文字コードに変換して、
文字コードを変数に入れたいんですけど、どうすればいいですか?



この記事に返信する


SYAM

リンク

2009/8/26(Wed) 15:50:38|NO.27328

一文字ずつということなら、peek() 関数で読み取れます。
もし、読み取った値が 0x81〜0x9f または 0xe0〜0xfc だった場合、それは全角文字の1バイト目ですからもう1バイト読み出すか、あるいは wpeek()関数で読み直します。
それ以外の値であれば、それは1バイト文字なのでそのままでOKです。



窓口

リンク

2009/8/26(Wed) 16:10:41|NO.27329

文字列をUnicodeに変換してから切り分けるという方法もあります。



skyblue

リンク

2009/8/26(Wed) 16:39:21|NO.27330

SYAMさんへ
peek()関数やwpeek()関数は16進数ですか?それとも10進数ですか?

窓口さんへ
具体的には、どうするのですか?



SYAM

リンク

2009/8/26(Wed) 17:30:03|NO.27331

peek(),wpeek()関数では「数値」がひとつ得られるだけです。
10進法とか16進法というのは、「数値を数字で表現する方法の種類」ですから、peek(),wpeek()関数には特に関係ありませんね。

もし、得られた「数値」を「数字」に直したいのであれば、strf()関数が便利でしょう。10進法にも16進法にもできます。

詳細はヘルプを参照してください。



Kpan

リンク

2009/8/26(Wed) 20:40:32|NO.27338

cnvstow命令、cnvwtos関数の説明をヘルプでチェック。



窓口

リンク

2009/8/27(Thu) 01:30:10|NO.27343

>>kpenさん
有難うございます。

Unicodeは日本人が日常で使う全ての文字が基本的に2byteに変換されるので、
全角、半角を意識せずに、文字操作が行えます。
お勧めです。

Unicodeで調べてみてもいいと思います。



skyblue

リンク

2009/8/27(Thu) 15:37:12|NO.27350

Unicodeをwikiで調べた結果、SYAMさんの言った方法でやることに決めました。ので、
peek()関数を使う場合の具体的なアルゴリズムを教えてくれますか?



SYAM

リンク

2009/8/27(Thu) 18:05:29|NO.27352

文字列を全部読み出したいのでしょうか?

やりたいことがわからないので、とりあえず、
「文字列の中の文字の文字コードを配列変数に格納する」アルゴリズムを以下に示します。


■読み取り対象の文字列のバイト数ぶんの要素を持つ配列変数を作る(これだと余る可能性がありますが、面倒なのでここでは可能性のある最大容量を確保しています。)
■配列変数の格納先を、配列変数の最初の要素とする

■読み取り位置を読み取り対象の文字列の先頭とします。(つまり、peek()関数で使う"インデックス"を 0 にします)

(これ以降の処理を、読み取り済みバイト数が 読み取り対象の文字列のバイト数と同じになるまで繰り返します。)

■peek() 関数で1バイト読み取り、配列変数に格納します。
■もし、読み取った値が 0x81〜0x9f または 0xe0〜0xfc だった場合、wpeek()関数で読み取り配列変数にもう一度格納しなおして、読み取り位置を1バイト後にずらします。
■読み取り位置を1バイト後にずらします。
■配列変数の格納先を1つ後にずらします。
(この時点での読み取り位置の値が、読み取り済みバイト数になっている。)

…です。
もし配列変数の要素を余らせないようにしたければ、事前に文字列内を全部調べて全角文字の個数を調べてから読み出すようにすればできるでしょう。
つまり、ループを2つ作ってやる必要があります。



SYAM

リンク

2009/8/27(Thu) 18:12:01|NO.27353

追記。

■peek() 関数で1バイト読み取り、配列変数に格納します。

のすぐ後に、

■もし、読み取り位置の値 +1 が、読み取り対象の文字列のバイト数と同じであれば、その時点で処理を完了とする。

…というのが必要ですね。



skyblue

リンク

2009/8/28(Fri) 20:51:47|NO.27373

SYAMさんへ
ファイルの文字列の変数の入出力です。



SYAM

リンク

2009/8/28(Fri) 21:28:14|NO.27374

では読み取り対象の文字列をファイルから読み出して処理しましょう
…としか言いようがないわけですが、質問は何ですか?



ANTARES

リンク

2009/8/29(Sat) 03:28:27|NO.27386

>文字列(1b文字と2b文字、特に2b文字)を一文字ずつ文字コードに変換して、
>文字コードを変数に入れたいんですけど、どうすればいいですか?

sep="," s="あいうえおabcdeかきくけこ" l=strlen(s) sdim t,l*4+1 p=0 repeat c=peek(s,p) if c>$80 & c<$A0 | c>$DF { p++ c=c<<16|peek(s,p) } ;t+=""+strf("%X",c)+sep ;16進 t+=""+c+sep ;10進 p++ if p>=l: break loop mes t



ANTARES

リンク

2009/8/29(Sat) 03:55:22|NO.27391

 あ、t+=strf(……でいいんだった。



skyblue

リンク

2009/8/29(Sat) 08:14:02|NO.27397

SYAMさんへ
0x81〜0x9f または 0xe0〜0xfcの判定式の所がわからないのです。
自分でいろいろとやってみたんですけど、うまくいかないのでコードを
教えてくださいますか?



SYAM

リンク

2009/8/29(Sat) 08:38:05|NO.27399

ご指名いただいたので一応レスしますが…

すでにANTARESさんがその答えを書いていらっしゃいます。
不等号で比較しているので、条件の式に出てくる数値は微妙に違いますが。



skyblue

リンク

2009/8/29(Sat) 13:36:03|NO.27405


imoji=peek(moji,index) ximoji=strf("%x",imoji) if ximoji>$80{ if ximoji<$9e{ imoji=wpeek(moji,index) ximoji=strf("%x",imoji) index+=2 } } else{ if imoji>$df{ if imoji<$fb{ imoji=wpeek(moji,index) ximoji=strf("%x",imoji) index+=2 } } index++ }
上記のようにしたらerror21とでてコンパイルできません。
どういう風にしたらいいでしょうか?



shinkun

リンク

2009/8/29(Sat) 16:52:20|NO.27407


if ximoji>$80{ if ximoji<$9e{
この部分を次のように変えてみましょう。

if imoji>$80{ if imoji<$9e{
問題が解決するはずです。


ところで、skyblue さんはプログラムを始めてまだ日が浅いのでしょうか?
16 進数とか文字列とか色々と誤解をしているようです。

2 進数・10 進数・16 進数は、数値の書き表し方の違いに過ぎません。すでに SYAM さんも説明されていますが。
例えば、16 という数値を表したい時、HSP では
2 進数: 0b10000 または %10000
10 進数: 16
16 進数: 0x10 または $10
以上のどの表記をしても良いのです。すべて 16 という数値の意味に解釈されます。

逆に言えば、以下の 2 つはどちらも同じ意味で全く同じ動作・処理をします。

if imoji>$80{ if imoji<$9e{ ------------------------------- if imoji>128{ if imoji<158{
skyblue さんのように

ximoji=strf("%x",imoji)
このようにして変換する必要はありません。そもそも、この変換は「数値」を「数字」列に変換しているので意味がちょっと違ってきます。


今回のエラーの原因を理解するには、もう少し話を掘り下げる必要があります。

HSP には整数型、実数型、文字列型があるのはご存知でしょうか?(他にもあります。)
加算や減算、あるいは、比較といった演算はデータ型の異なるもの同士では出来ません。
異なる物同士の演算をする場合、HSP は右項のデータ型を変換し、左項と揃えて演算を行います。

imoji=peek(moji,index) ximoji=strf("%x",imoji) if ximoji>$80{
この例において、imoji と $80 は整数型、ximoji は文字列型です。
条件式 ximoji > $80 において、文字列と数値を比較してますから、右側の $80 を文字列に変換します。つまり、ximoji > "128" となります。
しかし、> 演算は数値専用で、文字列に対しては適用出来ないため、そういう演算は出来ないとHSP が怒って error 21 が発生します。
なお、$80 < ximoji に修正すると、このエラーは発生しなくなります。その理由はもう分かるはずです。そして、最初に提示した方法とこの方法、どちらが効率が良いかも分かるはずです。



shinkun

リンク

2009/8/29(Sat) 17:06:14|NO.27408

> ANTARES さん


c=c<<16|peek(s,p)
ではなく、

c=c<<8|peek(s,p)
ではないでしょうか?



ANTARES

リンク

2009/8/30(Sun) 06:58:10|NO.27422

 ですね(^_^;;
失礼。



skyblue

リンク

2009/8/30(Sun) 12:18:19|NO.27437

できました。
教えてくださった皆様、ありがとうございました。



shinkun

リンク

2009/8/30(Sun) 13:10:40|NO.27441

> ANTARES さん

いえいえ、私もよくやるミスです。(^^;
そっとしておこうとも思ったんですが、skyblue さんの事も考えると手を出さずには入れませんでした。


> skyblue さん

どんなアプリケーションが出来上がるのか分かりませんが、頑張って下さいね!!



ONION software Copyright 1997-2023(c) All rights reserved.