[delphi-users:4620] バイト数を指定してワイド文字列を取得するには

648 views
Skip to first unread message

Quest

unread,
Feb 6, 2017, 12:19:43 AM2/6/17
to delphi...@freeml.com
いつもお世話になります。

UNICODE文字列の先頭から指定バイト数に完全に含まれる文字列を取得するには
どのようにすれば良いでしょうか。
'ABあい'という文字列に対して3(バイト)を指定したら
'AB'という文字列を取得したいんです。
ループで回しながら1文字ずつ取得する文字を増やし
その都度バイト数が制限を越えたか調べれば出来なくはないですが
明らかに効率は悪そうです。

この理由ですが、SYBASEでVARCHAR(20)と宣言されたフィールドに格納できるのが
20文字でなく20バイトまでなのでバイト数で制限しなければならないからです。
VARCHAR(20 CHAR)と宣言すればマルチバイト文字でも20文字まで格納できる様ですが
テーブル定義自体を変更するのはできそうにないのでアプリ側で切り詰めなければ
いけない状況です。

DB側でもWinAPIでも構いませんが何か一発で取得できる関数などはあるでしょうか。

皆様のお知恵をお貸しください。

環境はXE6です。


MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
今までダイエットに失敗してきたあなた
必見です!!やせる事に特化した専門店
ミスパリダイエットセンター☆彡☆彡
今なら、5,000円で体験実施中♪
http://ad.freeml.com/cgi-bin/sa.cgi?id=pE5EZ
------------------------------------------------------[freeml byGMO]--

DEKO

unread,
Feb 6, 2017, 12:56:36 AM2/6/17
to delphi...@freeml.com
こんにちは。

> UNICODE文字列の先頭から指定バイト数に完全に含まれる文字列を取得するには
> どのようにすれば良いでしょうか。
[System.SysUtils.ByteToCharIndex() / System.SysUtils.ElementToCharIndex()]
http://docwiki.embarcadero.com/Libraries/Seattle/ja/System.SysUtils.ByteToCharIndex
http://docwiki.embarcadero.com/Libraries/Seattle/ja/System.SysUtils.ElementToCharIndex

こんな奴でしょうか?ByteToCharIndex() / ElementToCharIndex() は文字インデックスまでしか
返さないので後段で Copy() して文字列を取得しなくてはなりませんが。

関数の意味がよく解らないのであれば、同等の関数を解説した
ページがありますので参考にしてみてください。

[MECSUtils.MecsElementToCharIndex()]
http://ht-deko.com/tech021.html#MecsElementToCharIndex
-- 
by DEKO
-----------------------------
 http://ht-deko.com/
 de...@ht-deko.minim.ne.jp
-----------------------------

Quest

unread,
Feb 6, 2017, 2:45:22 AM2/6/17
to delphi...@freeml.com
DEKOさん、こんにちは。

関数名はそのものズバリなんですが、非推奨のByteToCharIndex()でも
ByteToCharIndex('AあBC', 3)で3が返ってきます。
用意されたバッファ(この場合3バイト)に確実に格納できる文字列を
取得したいので、これで2が返って欲しいんです。
つまり指定されたバイト数の最後の部分で、文字コードの一部だけになった場合
その最後の文字は含まないようにしたいわけです。
推奨されているElementToCharIndex()で上記の動作をするのは分かるんですが。

とりあえず使用頻度も文字数も少ないので、下記の感じでゴリゴリ回してます。
function MBTrimming(const s: string, ByteCount: integer): string;
var
len: integer;
begin
len := ByteCount;
Result := Copy(s, 1, len);
while TEncoding.GetEncode(932).GetByteCount(Result) > ByteCount do
//とりあえずコードはShiftJISで
begin
Dec(len);
Result := Copy(s, 1, len);
end;
end;
これならUTF-8でもいけそうな感じですのでちょっと様子を見てみます。

ありがとうございました。
MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
■即戦力人材と企業をつなぐ転職サイト■
ビズリーチに【無料登録】すると・・・
・一流企業の求人情報を閲覧できます
・ヘッドハンターからスカウトが届きます
ビズリーチ【無料登録】ページはこちら
http://ad.freeml.com/cgi-bin/sa.cgi?id=pE7ia
------------------------------------------------------[freeml byGMO]--

DEKO

unread,
Feb 6, 2017, 3:03:05 AM2/6/17
to delphi...@freeml.com
> 関数名はそのものズバリなんですが、非推奨のByteToCharIndex()でも
> ByteToCharIndex('AあBC', 3)で3が返ってきます。

失礼しました。AnsiStrings ユニットを追加した上で、
AnsiStrings.ByteToCharIndex('AあBC', 3)
のようにして ANSI バージョンを呼び出してみてください。

[System.AnsiStrings.ByteToCharIndex() / System.AnsiStrings.ElementToCharIndex()]
http://docwiki.embarcadero.com/Libraries/ja/System.AnsiStrings.ByteToCharIndex
http://docwiki.embarcadero.com/Libraries/ja/System.AnsiStrings.ElementToCharIndex

Quest

unread,
Feb 6, 2017, 5:01:25 AM2/6/17
to delphi...@freeml.com
おぉ、そうですね。

ShiftJISならANSIバージョンでいけますね。
今回はこれでOKですが、UTF-8とかだと
ShiftJISでのバイト数とUTF-8でのバイト数に違いが出る場合が出てきますね。
とりあえず今回はShiftJISなのでANSIバージョンで対応します。

ありがとうございました。
---
このEメールはアバスト アンチウイルスによりウイルススキャンされています。
https://www.avast.com/antivirus


MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
あなたの息は大丈夫?
自分の息に自信のないあなたに!!
http://ad.freeml.com/cgi-bin/sa.cgi?id=pE8Jq
------------------------------------------------------[freeml byGMO]--

DEKO

unread,
Feb 6, 2017, 5:05:33 AM2/6/17
to delphi...@freeml.com
> 今回はこれでOKですが、UTF-8とかだと
> ShiftJISでのバイト数とUTF-8でのバイト数に違いが出る場合が出てきますね。

そんな時は MECSUtils です! Codepage を指定できます。

[MECSUtils.MecsElementToCharIndex()]
http://ht-deko.com/tech021.html#MecsElementToCharIndex

# 確か UTF-8 もいけたハズ。

--
by DEKO
-----------------------------
http://ht-deko.com/
de...@ht-deko.minim.ne.jp
-----------------------------


MLホームページ: http://www.freeml.com/delphi-users

----------------------------------------------------------------------
☆世界初☆17種類以上のお茶がワンタッチで楽しめる
ネスレのカプセル式お茶マシン「スペシャル.T」を今なら無料でお試し!
あなたの想像を超えるお茶の世界を♪♪
http://ad.freeml.com/cgi-bin/sa.cgi?id=pE8LY
------------------------------------------------------[freeml byGMO]--

Reply all
Reply to author
Forward
0 new messages