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


HSPTV!掲示板


未解決 解決 停止 削除要請

2021
0113
mikoto10000行以上のテキストに含まれている任意の文字列を改行に置換するプログラムの組み立てに困りごとです。9解決


mikoto

リンク

2021/1/13(Wed) 14:52:03|NO.92062

こんにちは。初めて掲示板に投稿するとmikotoと申します。
さっそく質問ですがUnicodeのテキストによる10000行以上のテキストに含まれている任意の文字列を改行に置換するプログラムの組み立てに困りごとです。
下記のプログラムを組み立てたのですが

#include "hsp3utf.as" sdim minamoto,10000000,1 ; 変数aは3文字までの文字列を10000つの要素で扱えます mesbox minamoto,150,150,5,10000000000000000000000000000000 button goto "改行する",*label stop *label strrep minamoto,":","\n" mesbox minamoto,150,150,5,100000000000000000000000000000000 stop
をHSP実行を押して実行結果のメッセージボックスに改行する10000行以上のUnicodeのテキストを入力して改行するボタンを押すと実行結果ウィンドウが消えてしまいます。
原因をしるために検索して自分でも調べていますが
皆様からヒントをもらえると助かります。
よろしくお願いします。



この記事に返信する


mikoto

リンク

2021/1/13(Wed) 17:50:10|NO.92064

あと、使用環境はWindows10でHSPのバージョンは3.5です。



沢渡

リンク

2021/1/13(Wed) 18:05:57|NO.92065

とりあえず気になることは、
・mesboxの第5パラメータの数値があまりにも大きすぎる。
 整数の最大値は2147483647ですし、現実的に考えてGB単位の文書を入力するなんて
まずありえないと思いますから、もう少し現実的な値にした方が良いでしょう。
(たとえばminamotoのサイズに合わせて10MB程度とか)
・このコードだと*labelを呼び出すたびに新しいメッセージボックスが作られてしまう。
 メッセージボックスの内容への反映はobjprmを使った方が良い。



TOMATO

リンク

2021/1/13(Wed) 18:28:58|NO.92066

UTF-8版のランタイムの不具合な気がします。
文字列が32767文字までは大丈夫ですが、それ以上になると落ちるっぽい。


// UTF-8版でなければ落ちない模様 #include "hsp3utf.as" // 長い文字列を用意 sdim s, 10000000 repeat 32768 // 32767 であれば落ちない poke s, cnt, '0' + cnt \ 10 loop // メッセージボックス表示&書き換え mesbox s, 640, 480, 1, -1 objid = stat objprm objid, s



TOMATO

リンク

2021/1/13(Wed) 19:45:54|NO.92068

多分、252行目のメモリ確保処理がUTF-8版において足りていない予感。
http://dev.onionsoft.net/trac/openhsp/browser/trunk/hsp3/win32gui/hspwnd_obj.cpp#L252


231 static void Object_StrInput( HSPOBJINFO *info, int wparam ) 〜略〜 248 if (size < 0x8000) { 249 bigbuf = minp; 250 val = GetDlgItemText( hwnd, cid, minp, 0x7fff ); 251 } else { 252 bigbuf = (HSPAPICHAR*)sbAlloc( size+1 ); 253 val = GetDlgItemText( hwnd, cid, bigbuf, size ); 254 }

横展開して確認してませんので、他にもあるかも…?



mikoto

リンク

2021/1/14(Thu) 13:14:04|NO.92070

沢渡様、TOMATO様、教えてくださりありがとうございます。
objprmを使ってメッセージボックスの内容を変えた方がボタンを押すたびに
新しいメッセージボックスを作らずにメッセージボックス命令も一回書くのみで成り立ちます。
#include "hsp3utf.as"の機能は文字列が32767文字までの受付を許すようです。
http://dev.onionsoft.net/trac/openhsp/browser/trunk/hsp3/win32gui/hspwnd_obj.cpp#L252
のページも見ましたがプログラムが長くてすこしよくわからないところがあるので保留にします。
Unicodeの32767文字までのテキストに含まれる任意の文字列を改行に置換するプログラムを組み立てなおしたのでのせておきます。
#include "hsp3utf.as" //文字列が32767文字までは大丈夫
screen 0, 369,369, screen_tool objmode 2,1 font "游明朝",24,16 title "テキストに含まれる任意の文字を改行に置換する。" sdim minamoto,2147483,1 sdim nyuuryoku,2147483,1 mes "32767文字までの文字列を入力" mesbox minamoto,369,150,5,2147483647 mes "下記に改行に置換する文字を入力" input nyuuryoku,369,100,0 objsize 369,36 button goto "改行に置換する",*label stop *label strrep minamoto,nyuuryoku,"\n" objprm 0,minamoto objprm 2,"改行に置換しました" stop
Unicodeの32767文字以上のテキストファイルは複数に分割して改行に置換にするとよいと思いました。
解決とします。ありがとうございました。



沢渡

リンク

2021/1/14(Thu) 13:14:40|NO.92071

あくまで応急処置ですが、winobjでメッセージボックスを作るのはどうでしょう?
処理はだいぶ面倒になりますが。

#include "hsp3utf.as" #const WS_CHILD 0x40000000 #const WS_VISIBLE 0x10000000 #const WS_BORDER 0x800000 #const WS_HSCROLL 0x100000 #const WS_VSCROLL 0x200000 #const ES_AUTOHSCROLL 0x80 #const ES_AUTOVSCROLL 0x40 #const ES_MULTILINE 0x4 #const EM_SETLIMITTEXT 0xC5 #const WM_GETTEXTLENGTH 0xE #const WM_GETTEXT 0xD #const WM_SETTEXT 0xC winobj "EDIT","",0,WS_CHILD|WS_VISIBLE|WS_BORDER|WS_HSCROLL|WS_VSCROLL|ES_AUTOHSCROLL|ES_AUTOVSCROLL|ES_MULTILINE,150,150 id_edit=stat h_edit=objinfo(id_edit,2) sendmsg h_edit,EM_SETLIMITTEXT,10000000,0 //書き込める文字数の上限を1千万文字に(UTF-16なのでバイト数ではなく文字数) button gosub "改行する",*label stop *label gosub *gettext strrep minamoto,":","\n" sdim buf,strlen(minamoto)*2+2 //UTF-8からUTF-16に変換するためのバッファ cnvstow buf,minamoto //変換 sendmsg h_edit,WM_SETTEXT,0,varptr(buf) //エディットボックスに更新した文章を反映 dim buf //バッファを解放 return *gettext //minamotoにエディットボックスの内容を反映 sendmsg h_edit,WM_GETTEXTLENGTH,0,0 //文字数を取得 size=stat+1 //末端にNULLを追加 sdim buf,size*2 //UTF-16は1文字2バイトなのでsizeの2倍のバッファを確保 sendmsg h_edit,WM_GETTEXT,size,varptr(buf) //エディットボックスから文字列を取得 minamoto=cnvwtos(buf) //UTF-16からUTF-8に変換 dim buf //バッファを解放 return



沢渡

リンク

2021/1/14(Thu) 13:15:42|NO.92072

あっと、すれ違いでした。
解決されたようですが、あくまでも参考までにということで。



mikoto

リンク

2021/1/14(Thu) 13:32:38|NO.92073

沢渡様、追加の回答ありがとうございます。
#include "hsp3utf.as"
#const WS_CHILD 0x40000000
#const WS_VISIBLE 0x10000000
#const WS_BORDER 0x800000
#const WS_HSCROLL 0x100000
#const WS_VSCROLL 0x200000
#const ES_AUTOHSCROLL 0x80
#const ES_AUTOVSCROLL 0x40
#const ES_MULTILINE 0x4

#const EM_SETLIMITTEXT 0xC5
#const WM_GETTEXTLENGTH 0xE
#const WM_GETTEXT 0xD
#const WM_SETTEXT 0xC

winobj "EDIT","",0,WS_CHILD|WS_VISIBLE|WS_BORDER|WS_HSCROLL|WS_VSCROLL|ES_AUTOHSCROLL|ES_AUTOVSCROLL|ES_MULTILINE,150,150
id_edit=stat
h_edit=objinfo(id_edit,2)
sendmsg h_edit,EM_SETLIMITTEXT,10000000,0 //書き込める文字数の上限を1千万文字に(UTF-16なのでバイト数ではなく文字数)

button gosub "改行する",*label
stop

*label
gosub *gettext
strrep minamoto,":","\n"
sdim buf,strlen(minamoto)*2+2 //UTF-8からUTF-16に変換するためのバッファ
cnvstow buf,minamoto //変換
sendmsg h_edit,WM_SETTEXT,0,varptr(buf) //エディットボックスに更新した文章を反映
dim buf //バッファを解放
return

*gettext
//minamotoにエディットボックスの内容を反映
sendmsg h_edit,WM_GETTEXTLENGTH,0,0 //文字数を取得
size=stat+1 //末端にNULLを追加
sdim buf,size*2 //UTF-16は1文字2バイトなのでsizeの2倍のバッファを確保
sendmsg h_edit,WM_GETTEXT,size,varptr(buf) //エディットボックスから文字列を取得
minamoto=cnvwtos(buf) //UTF-16からUTF-8に変換
dim buf //バッファを解放
return
のプログラムを分析してみます。



mikoto

リンク

2021/1/14(Thu) 13:39:35|NO.92074

すこし関係ある話ですが翻訳の実行過程も置換命令の応用ですね。



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