shift_jis_macro.hsp

HSPでシフトJISの日本語文字列を1文字ずつ正しく表示するTips

こんにちは。HSP(Hot Soup Processor)でプログラミングを楽しんでいる皆さん、今日はシフトJISエンコーディングの文字列を扱う際のちょっとしたテクニックをご紹介します。HSPの標準環境では、文字列は基本的にシフトJIS(SJIS)で扱われます。英語(ASCII)部分は1バイトですが、日本語の全角文字(ひらがな、カタカナ、漢字など)は2バイトで表現されます。そのため、単純にstrlenでバイト数をループしてstrmid(txt, cnt, 1)で1バイトずつ取り出してしまうと、全角文字が途中で切れて文字化けしてしまうことがあります。これを避けるために、全角文字の先頭バイト(リードバイト)を判定して、2バイト文字の場合はまとめて取り出す処理が必要です。以下のようなマクロとループを使って、混在文字列を正しく1文字ずつ表示(または処理)できます。

// 判定用マクロ、パラメータに持E$FFFD$FFFDした文字コードがシフトジスのリードバイトか調べめE
// シフトジスのリードバイチEなめE1 が返る、E$FFFD$FFFDえ$FFFDE 0 が返る
#define global ctype IS_SJIS(%1) ( ( $81 <= (%1) ) & ( (%1) <= $9f ) | ( $e0 <= (%1) ) & ( (%1) <= $fc ) )
txt = "abcあいぁEyz"
repeat strlen(txt)
code = peek(txt, cnt)
if IS_SJIS(code) {
mes strmid(txt, cnt, 2)
pos GINFO_CX + GINFO_MESX + 8, 0
continue cnt + 2
} else {
mes strmid(txt, cnt, 1)
pos GINFO_CX + GINFO_MESX + 8, 0
}
loop

解説IS_SJISマクロ:シフトJISの全角文字のリードバイト範囲(0x81〜0x9F または 0xE0〜0xFC)をチェックしています。この範囲のバイトが来たら、続くバイトと合わせて2バイト文字だと判断します。
peek(txt, cnt) でバイト単位でコードを取得。
全角ならstrmid(…, 2)で2バイト取り出し、半角なら1バイト。
mesで表示し、posでカレントポジションを調整(GINFO_CXは現在のX座標、GINFO_MESXは直前に表示した文字の幅)。これで横に並べて表示できます。調整値(+8など)はフォントサイズや好みに合わせて変えてください。
repeat … loop内でcnt +=を適切に使うことで、バイト位置を正しく進めています。

この方法を使えば、「abcあいぁEyz」のような混在文字列も、a b c あ い ぁ E y z と正しく1文字ずつ表示されます。HSPは古い言語ですが、こうした低レベルなバイト操作が簡単にできるのが魅力ですよね。ゲームのテキスト表示や、独自のフォント描画などに活用してみてください!何か質問があればコメントでお知らせください。楽しいHSPライフを!

AIのGrokさんに文章を生成してもらいました。(2025/12)

コメント

タイトルとURLをコピーしました