ab.com コミュニティ

ActiveBasicを通したコミュニケーション
現在時刻 - 2024年3月29日(金) 03:10

全ての表示時間は UTC+09:00 です




新しいトピックを投稿する  トピックへ返信する  [ 8 件の記事 ] 
作成者 メッセージ
投稿記事Posted: 2014年6月11日(水) 12:39 
オフライン

登録日時: 2009年3月29日(日) 15:45
記事: 106
お世話になっております。
文字列を置換する関数を探していたのですが、どうしても見つからず自作しています。

以下の様なコードを書いているのですが、最後の方の
buffer = realloc(buffer,lstrlen(buffer) + lstrlen(SubText) + 1)
で、再確保するときにエラーが出ます。

具体的な内容として、
置換対象文字列<置換後文字列の時、メモリ不足と言われます。
デバッグモードで実行していると、bufferのポインタが0になっていました。

何かお気づきの点がございましたら、ご教授いただけると幸いです。

一応関数の説明も記載しておきます。
・BaseData As BytePtr:置換対象の文章データを入れます。
・SearchText As BytePtr:検索する文字列(置換される文字列?)を入れます。
・SubText As BytePtr:置換後の文字列を入れます。


BaseData:女の子『今日もいい天気だね』
SearchText:女の子『
SubText:女の子の名前「

女の子の名前「今日もいい天気だね』

コード:
Function SubstitutionText(BaseData As BytePtr,SearchText As BytePtr,SubText As BytePtr) As BytePtr
	Dim StartPos As Long
	Dim EndPos As Long
	Dim Text As String
	Dim buffer As BytePtr
	Dim Length As Long

	StartPos = 1
	EndPos = 1
	buffer = NULL


	Do
		'debug
		StartPos = InStr(StartPos,BaseData,MakeStr(SearchText))
		
		'開始文字がなければループを抜ける
		If StartPos <= 0 Then
			Text = Mid$(MakeStr(BaseData),EndPos)

			If buffer = NULL Then
				buffer = malloc(lstrlen(buffer)+lstrlen(Text) + 1)
				lstrcpy(buffer,Text)
			Else
				realloc(buffer,lstrlen(buffer)+lstrlen(Text) + 1)
				lstrcat(buffer,Text)
			End If

			Exit Do
		End If


		'スタートポジションまでを変数に格納
		If StartPos = EndPos Then
			'すぐに次の置換対象文字があった場合
			Text = Mid$(MakeStr(BaseData),StartPos,lstrlen(SubText))
			StartPos = StartPos + lstrlen(SubText)
		Else
			Text = Mid$(MakeStr(BaseData),EndPos,StartPos - EndPos)
		End If

		If buffer = NULL Then
			buffer = malloc(StartPos)
			lstrcpy(buffer,Text)
		Else
			buffer = realloc(buffer,StartPos)
			lstrcat(buffer,Text)
		End If
		

		'置換処理
		'd("Allbuffer:"+Str$(lstrlen(buffer) + lstrlen(SubText) + 1)+Ex"\r\nbuffer:"+Str$(lstrlen(buffer))+Ex"\r\nSubText:"+Str$(lstrlen(SubText))+Ex"\r\nSubText:"+MakeStr(SubText)+Ex"\r\nbuffer:"+MakeStr(buffer))
		buffer = realloc(buffer,lstrlen(buffer) + lstrlen(SubText) + 1)
		lstrcat(buffer,SubText)

		'終了ポジションを確定
		EndPos = StartPos + lstrlen(SearchText)

		'スタートポジションを進める
		StartPos = StartPos + lstrlen(SearchText)

	Loop

	SubstitutionText = buffer

End Function

_________________
↓個人的ソフト置き場
http://www.software.jpn.org/
↓萌えゲー製作とかしていたい
http://www.holygate.jpn.org/


通報する
ページトップ
投稿記事Posted: 2014年6月12日(木) 15:09 
オフライン

登録日時: 2006年2月05日(日) 17:10
記事: 215
お住まい: 東京都
まず実行するとへんな文字?が設定されて異常終了しました。
そしてイベントログで例外コード(0xc0000005:メモリアクセス違反)を確認しました。
また提示されたソースコードを確認したところおかしな箇所が一箇所ありました。

SubstitutionTextの25行目です。
realloc(buffer,lstrlen(buffer)+lstrlen(Text) + 1)
これだとせっかく再確保されたアドレスが取得できません。
realloc(buffer,lstrlen(buffer)+lstrlen(Text) + 1)
            ↓
buffer = realloc(buffer,lstrlen(buffer)+lstrlen(Text) + 1)
正常終了しました。
確認環境はWindows7 Home/SP1 X86です。
ただ、結果が期待どおりになりませんでした。
”女の子『今日も女の子の名前「だね』”となります。
ご確認よろしくお願いします。

余談ですが水波形さんのPCはたしかWindows7 Home/SP1 X64ですよね?。
AB4.24で、プラットフォームセレクトをWin32でコンパイルしましたか?


通報する
ページトップ
投稿記事Posted: 2014年6月13日(金) 00:21 
オフライン

登録日時: 2009年3月29日(日) 15:45
記事: 106
たかせ様

ご返信有難うございます。
引用:
SubstitutionTextの25行目です。
realloc(buffer,lstrlen(buffer)+lstrlen(Text) + 1)
これだとせっかく再確保されたアドレスが取得できません。
realloc(buffer,lstrlen(buffer)+lstrlen(Text) + 1)
            ↓
buffer = realloc(buffer,lstrlen(buffer)+lstrlen(Text) + 1)
正常終了しました。
こ、これはお恥ずかしい。
完全に抜けておりました。

こちらでも確認した所、短文ではエラーなく終わるようですが長文になるとアクセスエラーが起こります……
場所は、置換処理の「lstrcat(buffer,SubText)」でその時のエラーが以下のものです。
引用:
スレッド(&H6F4)はコード &H0 で終了しました。
HEAP[ScenarioEditor_debug.exe]: Heap block at 004EEDC0 modified at 004EEE3B past requested size of 73
スレッド(&HC2C)のブレーク ポイント(EPI=&H77230574)。
HEAP[ScenarioEditor_debug.exe]: Invalid address specified to RtlReAllocateHeap( 004D0000, 004EEDC8 )
スレッド(&HC2C)のブレーク ポイント(EPI=&H77230574)。
スレッド(&HC2C)でアクセス違反がありました(EPI=&H76692B73)。
何度かヒープのワーニングが出た後、アクセス違反が起こります。
この時、MessageBoxで中身を確認した所、バッファ(変数「buffer」)が0(空)になっていました。

なぜかが全くわかりません……

また、書き忘れておりましたが、ActiveBasic4.24.00で開発しております。
Win32でコンパイルしております。
PC環境は仰るとおり、Windows7 Home/SP1 X64です(そろそろ買い換えたい)。
申し訳ありません。

_________________
↓個人的ソフト置き場
http://www.software.jpn.org/
↓萌えゲー製作とかしていたい
http://www.holygate.jpn.org/


通報する
ページトップ
投稿記事Posted: 2014年6月15日(日) 23:57 
オフライン

登録日時: 2006年2月05日(日) 17:10
記事: 215
お住まい: 東京都
長文って何バイト位ですか?

状況から、おそらくlstrcatが失敗になっている可能性があります。
またlstrcatが失敗すると戻り値にNULLが設定されます。
そこで失敗(エラー)の理由を確認する方法として、
①lstrcatの直後にGetLastError関数を使用して直前のエラーコード取得します。
②FormatMessage関数でそのエラーコードに対応するシステムメッセ―ジを取得します。
もしかしたらこれで原因がわかるかもしれません。
ただ上記①、②に到達する前に異常終了する可能性もあります。
上記の関数はWin32ApiでABのヘルプに仕様が記載されています。
ご確認よろしくお願いします。

ふさわしくない質問ですみませんが水波形さんのPCのCPUはIntelですか?Amdですか?
よろしくお願いします。


通報する
ページトップ
投稿記事Posted: 2014年6月18日(水) 02:18 
オフライン

登録日時: 2009年3月29日(日) 15:45
記事: 106
ご返信有難うございます。
引用:
①lstrcatの直後にGetLastError関数を使用して直前のエラーコード取得します。
②FormatMessage関数でそのエラーコードに対応するシステムメッセ―ジを取得します。
こちらをやってみたところ、

reallocで「このコマンドを実行するのに十分な記憶領域がありません」

と出ます。
何故かどこかでバッファが破壊されてしまっているのか……?などと考えていますが、
原因が思いつきません。
引用:
水波形さんのPCのCPUはIntelですか?Amdですか?
Intel(R) Core i7 860 @2.80GHzです。
この辺りは詳しくないのですが、プログラミングに関係してくるのでしょうか…?
やはりハードも勉強していかなければいけませんね……

_________________
↓個人的ソフト置き場
http://www.software.jpn.org/
↓萌えゲー製作とかしていたい
http://www.holygate.jpn.org/


通報する
ページトップ
投稿記事Posted: 2014年6月20日(金) 03:39 
オフライン

登録日時: 2009年3月29日(日) 15:45
記事: 106
すいません、自己解決しました。
引用:
If buffer = NULL Then
buffer = malloc(StartPos)
lstrcpy(buffer,Text)
Else
buffer = realloc(buffer,lstrlen(buffer) + lstrlen(Text) + 1)
lstrcat(buffer,Text)
End If
ですね。

後は、
引用:
ただ、結果が期待どおりになりませんでした。
”女の子『今日も女の子の名前「だね』”となります。
ご確認よろしくお願いします。
これだけです……どうしたものか

_________________
↓個人的ソフト置き場
http://www.software.jpn.org/
↓萌えゲー製作とかしていたい
http://www.holygate.jpn.org/


通報する
ページトップ
投稿記事Posted: 2014年8月27日(水) 21:27 
解決していれば無視してください。
データベース処理を良くやっているので
データの差し替えとして書きます。
この場合は、
①データ群の中に、差し替え対象データのキーがあるかまず調査する
 この時にあれば、その位置を返答する
②返答で有り判定であれば、そこから差し替えをする。
 ABCDEFのCからXYZにしたい場合
 ABを返答用に用意する。
 XYZをそれに付け足す
 CからXYZ分ずらした場所の文字Fを付け足す
③データ群を破棄して返答用に差し替える
と、3手順に分けたほうが、データの動きを把握できて良いと思います。
必要であればコード書いてみますんで。。


通報する
ページトップ
   
投稿記事Posted: 2014年10月19日(日) 01:15 
オフライン

登録日時: 2009年3月29日(日) 15:45
記事: 106
kobo様

ありがとうございます。
記載を忘れておりましたが、こちらの質問は解決済みとなります。

また、完成した文字列置換アルゴリズムを「実践コードモジュール」にて掲載していますので、
興味のある方はどうぞ
http://www.activebasic.com/forum/viewto ... f=2&t=4561

_________________
↓個人的ソフト置き場
http://www.software.jpn.org/
↓萌えゲー製作とかしていたい
http://www.holygate.jpn.org/


通報する
ページトップ
期間内表示:  ソート  
新しいトピックを投稿する  トピックへ返信する  [ 8 件の記事 ] 

全ての表示時間は UTC+09:00 です


オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[17人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
Powered by phpBB® Forum Software © phpBB Limited
Japanese translation principally by ocean