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


HSPTV!掲示板


未解決 解決 停止 削除要請

2021
0703
kenNull文字が含まれているテキストからNull文字を削除するには4解決


ken

リンク

2021/7/3(Sat) 16:26:05|NO.93148

会社の会計ソフトからデータをcsv形式で出力させて、そのデータを処理する目的で、
HSPでスクリプトを書いているのですが、noteselを使って読み込むとどうしてもテキストファイルの
特定のところで切れてしまうので、csvファイルを調べてみると、Null文字が含まれていることが
原因だとわかりました。バイナリデータとして読込めばよいと思うのですが、その後の処理をテキスト
データとして扱うには結局Null文字を削除する必要が・・・。そもそもテキストとして扱えないので
strrepやstrtrimを使うことも出来ず行き詰っています。
どのような方法があるのか教えていただけないでしょうか?



この記事に返信する


ふにくら

リンク

2021/7/3(Sat) 16:46:47|NO.93149

NULL文字の位置ならstrlenで分かりませんか?
,泙existでファイルサイズを取得、バイナリとしてsdimにbload
⊆,strlenでNULLのインデックスを取得し、
△離ぅ鵐妊奪スにpokeで半角スペース(0x20)か何か適当な代わりの文字を書き込む

◆銑をstrlen==ファイルサイズになるまで繰り返す。
こんな方法でいかがでしょうか。

試してないのでアレですが、仮にstrlenがダメでもC標準関数のstrchrとかで行けるかと。
使い方はググれば出てきますよ。
#uselib "msvcrt"
#cfunc global strchr "strchr" var,int



GENKI

リンク

2021/7/3(Sat) 19:43:50|NO.93150

null文字をどのような意味のデータとして扱うかによって対処法が変わってくると思います。

とりあえず無視するデータとして考えてみました。
bloadでもいいですが、noteloadで読み込んだ後にnull文字を問題ない文字に置き換えるしかないんじゃないでしょうか。

; 元の文字列 sdim a a = "abcdef" mes a l = strlen(a) ; null文字混入 poke a, 3, 0 mes a ; null文字を取り除く repeat l if peek(a, cnt) = 0 { poke a, cnt, ' ' ; スペースに置き換え } loop mes a
null文字の部分を削除したい場合も同じように全文字ループで探して、他の変数に移し替えるという手順になります。



とあるプログラマ

リンク

2021/7/3(Sat) 20:30:07|NO.93151

モジュールとして作ってみました。

私のスクリプトの場合はヌル文字を削除するようにしてあります。
文字コードはShift-JISのみで、Unicodeには対応していません。

ファイルでは試していませんが、bloadでも対応しているはずです。


#module // 型を var ではなく str にするとヌル文字以降が切り落とされるので注意 #deffunc RemoveNullChar var text, \ local index, local merged // ↑再帰するのでローカル変数であること // ヌル文字の次の文字のインデックス index = strlen(text) + 1 repeat if (index == varsize(text)) : break if (peek(text, index) == 0) : index++ : else : break //2文字以上のヌル文字の連続を検知 loop // インデックスはヌル文字が連続していれば、最後のヌル文字 + 1 を指す。 // 即ち インデックス=変数サイズ であれば終端以外にヌル文字が無いことを示す if (index == varsize(text)) : return // 変数初期化 sdim merged, strlen(text) + (varsize(text) - index) // ヌル文字までの文字数 + (全体数 - ヌル文字の次のインデックス): 即ち残りの文字数 // 変数に内容をメモリコピー (普通のイコール代入や文字列関連の命令だと、ヌル文字以降が切り落とされてしまう) memcpy merged, text, strlen(text) // ヌル文字までをコピー memcpy merged, text, varsize(text) - index, strlen(text), index // ヌル文字以降をコピー // ヌル文字の次の文字のインデックスが変数サイズに満たなければ残りがあるということなので再帰処理を行う if (index < varsize(text)) : RemoveNullChar merged // この時点で終端以外のヌル文字は削除されてなければならない sdim text, strlen(merged) text = merged return #global text = "ABCDEFGHIJKLMNOPQRSTUVWXYZあいうえおかきくけこ0123456789" poke text, 5, 0 // F をNULL文字に poke text, 6, 0 // G をNULL文字に poke text, 15, 0 // P をNULL文字に wpoke text, 31, 0 // う をNULL文字に (日本語は2バイト) mes "変換前" mes text mes RemoveNullChar text mes "変換後" mes text



ken

リンク

2021/7/4(Sun) 08:42:17|NO.93152

ふにくらさん、GENKIさん、とあるプログラマさんご教授ありがとうございます。
ふにくらさん、GENKIさん
Null文字を他の文字に置換して、その後削除するという方法があったのですね、私は直接取り除こうと考え、とあるプログラマさんのようにNull文字までを別変数aに代入し、Null文字の次のインデックス
以降の文字列を別変数bにコピーしそれを変数aに追記するという操作を繰り返すことでNull文字を取り除こうとしていました。
でも、変数bに文字列がコピーされず上手くいきませんでした。
とあるプログラマさんのモジュールを拝見させていただき原因が解りました。
私、変数を代入する際に = を使用していました。= の特性を理解していませんでした。
Null文字を別文字に変換する方法をだとつまずいていなかったように思いました。

とあるプログラマさんモジュールありがとうございました。
varsizeやmemcpyの存在は知っていましたが、どのような場合に使用するのか分りませんでした。
同様の手順を考えていたのですが、このようにすっきりしたスクリプトになるんだと驚きました。
実際のcsvファイルで試しました。ファイルサイズが大きいので、多少時間がかかる処理にはなりますが、確実にNullは削除できました。

ふにくらさん、GENKIさん、とあるプログラマさん
本当にありがとうございました。



記事削除

記事NO.パスワード
(質問が解決したスレッドは他の利用者に活用してもらうため、削除しないようお願いします)

NO.93148への返信

マスコット

好きなマスコットを選んでください。

名前

e-mail
HOME
  1. 初めて利用する方は、HSP3掲示板の使い方をお読みください。
  2. 不要部分の多い長いスクリプトの投稿は ご遠慮ください。
  3. 書き込みは自動改行されません。適度に改行を入れてください。
  4. スクリプトは小文字の<pre>〜</pre>で囲むと見やすく表示できます。

削除用パスワード

解決したら質問者本人がここをチェックしてください。

エラー発生時、再送信すると二重送信になることがあります。
回答が得られたら、お礼書き込み時に[解決]チェックしてください。
SPAM防止のためURLから始まる文章は投稿できません。
SPAM防止のため英文字のみの本文を投稿することはできません。

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