@IT会議室は、ITエンジニアに特化した質問・回答コミュニティ「QA@IT」に生まれ変わりました。ぜひご利用ください。
- PR -

文字列をバイト単位で切り分けたい。

投稿者投稿内容
きくちゃん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 854
お住まい・勤務地: 都内某所
投稿日時: 2004-01-19 13:25
ほむらさん、こんにちは。

引用:

引用:

(4は捨てる) ←※特にこの辺


桁ずれのエラーを出力してもいいような気がします。
DBに登録するのであれば事前のエラーチェックは厳しくして良いと思うのです。


規格の違うレガシシステム同士でデータを交換するためのプログラムを書いているとか...。

引用:

引用:

固定長のCSVファイルからDBにレコードを取り込むために、
何バイト目から何バイトの文字列という形で区切りたいのです。
その文字列には半角文字・全角文字が混在するので、
何文字分という切り出し方ではいけないのです。 ←こことか


場所で決定しているのが固定長のメリットです。



例えば、レコード長が 9バイト で、先頭〜4バイト目、5バイト目〜9バイト目で項目が分かれるよう定義されている場合、以下のような(非Unicodeの)テキストファイルは有効ですよね?

コード:
1---5----
AB  12345
あい67890


vb.netの Mid 関数とか、System.String.Substring メソッドの場合、「何バイト目」というような切り出しが出来ないので、上記の例で、開始位置を5文字目、長さを5文字、と指定して2番目の項目の値を取得しようとした場合、2レコード目で失敗してしまうんです。
なので、他の方の投稿にあるように、一旦、shift-jis に変換して、さらにバイト配列に変換するなりしないと、2バイト文字を含む固定長データを正しく処理出来ないんですよね。
でまあ、「一発で何とかならない? 前は出来たんだから」という事のようです。

ちなみに、「Visual Basic 言語リファレンス」によれば、

引用:

以前のバージョンの Visual Basic では、MidB 関数は文字数ではなくバイト数に基づいて文字列を返していました。これは主に、2 バイト文字セット (DBCS) アプリケーションで文字列を変換するために使用します。Visual Basic .NET のすべての文字列は Unicode で、MidB はサポートされていません。


だそうです>元質問者さん
にのっち
会議室デビュー日: 2004/01/18
投稿数: 8
投稿日時: 2004-01-19 14:08
みなさまいろいろなご意見ありがとうございます。
こういった場所に投稿して、自分のしたいことにより近い意見を頂くには、
最初に適切な説明が必要ということを学びました。

私のしようとしていることは、
他システムで作られた固定長のテキストファイルを、
何バイト目から何バイト分はこの項目に…という形で切り出して、
1行1レコードとしてDBに格納するという処理です。

ですので、元ファイルの形式をこちらで調整することはできません。
DBのレングスは、桁あふれしないように持っているので、
DB更新時に桁あふれのエラーになることはありません。

最終的に、デフロボさんから頂いたソースを改造して、
使用させて頂くことにしようかと思います。
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2004-01-19 14:36
引用:

にのっちさんの書き込み (2004-01-19 14:08) より:
他システムで作られた固定長のテキストファイルを、
何バイト目から何バイト分はこの項目に…という形で切り出して、
1行1レコードとしてDBに格納するという処理です。



Jubeiさんの「投稿日時: 2004-01-19 10:20」の投稿でも指摘されていますが、
それなら、EncodingのGetStringメソッドで事足りるのでは?
xバイトからyバイト分をByte配列に取り込み、SJISのEncodingインスタンスの
GetStringにこのByte配列を渡せば、それを文字列化できます。
さらに、1データのうち空いているバイト数分だけ、
半角空白などでパディングしてあるなら、Trimメソッドで切り詰めればよいでしょう。
にのっち
会議室デビュー日: 2004/01/18
投稿数: 8
投稿日時: 2004-01-19 16:06
EncodingのGetStringで簡単にできました!

最初Jubeiさんに教えて頂いたときには、
Unicodeエンコーディングを使おうとしていたので、
文字単位での取得しかできなかったようです。

文字コードについての理解が足りないために、
回り道してしまいましたが、いろいろと勉強になりました。
ありがとうございました。
べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2004-01-19 16:47
にのっちさん、解決したということでおめでとうございます。

でも、
引用:
"1234512345アイウエオあいうえお"という文字列があったとして、
8バイト目から5バイトの文字列⇒"23"(4は捨てる)


こういうのはどうやりました?捨てるべき全角文字の1バイト目がくっついてきちゃう
気がしたのです。もっともshift-jisの1バイト目は半角文字とかぶらないように
なってているので文字として見えることはなさそうですが。

また、"01234512345アイウエオあいうえお"のとき「8バイト目から5バイト」とると
"P23"になってしまいませんか?
私は、境目をまたぐ2バイトで
if(Encoding.GetEncoding("Shift_JIS").GetString(bytes,〜〜,2).Length==1)
のようなことをすればいいのかなと思ったのですが。

[編集]

なるほど、そうですね(汗)
しかもよく考えたら、前の段階で捨てられた全角文字を1バイト目から
数えるようにすればそのようなことはおきないですね。

[ メッセージ編集済み 編集者: べる 編集日時 2004-01-19 17:25 ]
ゆうじゅん
ぬし
会議室デビュー日: 2004/01/16
投稿数: 347
投稿日時: 2004-01-19 17:09
横槍失礼いたします。

>私は、境目をまたぐ2バイトで
>if(Encoding.GetEncoding("Shift_JIS").GetString(bytes,〜〜,2).Length==1)
>のようなことをすればいいのかなと思ったのですが。

全角2byte目と1byte目のコードが重なる場合があるので

境目2バイトを見た場合
(全角1byte目)+(全角2byte目)
(全角2byte目)+(次の文字の全角1byte目)
の区別がつかないため文字列の先頭からチェックする必要があると思います。




[ メッセージ編集済み 編集者: ゆうじゅん 編集日時 2004-01-19 17:28 ]
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2004-01-19 17:22
他システムが正しいデータを生成しているのであれば多バイト文字が切れることはないんじゃないんですか?
つまり切れるということは渡されるデータがおかしいので、にのっちさんの作る部分ではどうしようもないと思います。

前に同じような話題があったな〜と思って検索したら、バイトを指定して切り出すときの話がありました。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=3977&forum=7
もし多バイト文字が切れるなら、最後の一バイトだけ確認してもだめですよね。

>べるさん
境目をまたぐ2バイトの1バイト目が、たまたま2バイト文字の2バイト目でかつ境目をまたぐ2バイトで一文字として読めた場合まずくないですか?
「亜A」という文字列で「亜」の2バイト目と「A」でたまたま漢字の「意」として読めてしまったとか。

----------------
おおっともろかぶり
というか私の方が非常に遅い

[ メッセージ編集済み 編集者: 一郎 編集日時 2004-01-19 17:23 ]
ほむら
ぬし
会議室デビュー日: 2003/02/28
投稿数: 583
お住まい・勤務地: 東京都
投稿日時: 2004-01-19 18:07
ども、ほむらです。
-----
----
Jitta氏 、きくちゃん氏へマルチレスですm(__)m
----
Jitta氏:
引用:

 例えば、別のところが作ったプログラムがそのようなものを吐き出していた場合、手直しできなかったりするんですね。
#現在あるシステムの一部リプレースなど


きくちゃん氏:
引用:

規格の違うレガシシステム同士でデータを交換するためのプログラムを書いているとか...。


他システムからのデータ移行という場面は考えてませんでした^^;;;;
もし、移行とかだったら元データはいじれませんよねー(反省
大元ばかり疑ってしまうのは悪い癖ですね。

おなじく、きくちゃん氏へ
引用:

引用:

--------------------------------------------------------------------------------
その文字列には半角文字・全角文字が混在するので、
何文字分という切り出し方ではいけないのです。 ←こことか
--------------------------------------------------------------------------------
場所で決定しているのが固定長のメリットです。


例えば、レコード長が 9バイト で、先頭〜4バイト目、5バイト目〜9バイト目で項目が分かれるよう定義されている場合、以下のような(非Unicodeの)テキストファイルは有効ですよね?
コード:
1---5----
AB  12345
あい67890




説明不足でした。僕の言っていることも同じ事です。
ここでいう場所とは、桁位置のことを意図していました。
なので固定長であればバイトが全てなので半角/全角とか関係ないなと思ったわけです
#バイトと文字の違いが曖昧でした。。。

スキルアップ/キャリアアップ(JOB@IT)