Cで日本語検索

[上に] [前に] [次に]
PTAN [E-Mail] 1999/12/22(水) 10:52:10
Perlの場合、日本語(2バイト文字)の置換はjcode.plのtrを
使っていたのですが、それと同等の機能を持ったCライブラリって、
ありませんでしょうか?

ラウォッチ 1999/12/22(水) 12:57:35
私は -ljcode を使用していますが、NEC系のUNIXです。
EUC to JIS 又は JIS to EUC は自力でも結構簡単ですよ!

B-Cus 1999/12/23(木) 01:05:21
libjcode は *文字列の* 変換はできないようで。

ライブラリなんて探せばたくさん見つかるだろうと思ったんですが、
なさげですね。みんなどうやってるんでしょう?

http://www.din.or.jp/~ohzaki/perl.htm#JP_Match を見ながら
regex でやるという手もあるけど、mbstowcs で wchar_t に
変換しておけば、文字境界の問題は回避できるのかな? (よくわかってない)

ラウォッチ 1999/12/23(木) 08:53:24
はずしました。
置換ですね!
わたしは、 strstr()でループでまわします!

PTAN 1999/12/23(木) 10:09:54
ラウォッチさん、B-Cusさん、ご回答ありがとうございます。

> わたしは、 strstr()でループでまわします!

これだと、EUCの場合、前後1バイト共に0xA1〜0xFEなので、
後1バイトと前1バイトでヒットしてしまう恐れがあると思うのですが。

で、自力で組んでみたところ...
EUCの場合、最初の文字から〜0x7F,0x8E,0x8F,0xA1〜0xFEで場合分け
しながら、カーソルを進め、1文字ずつ検索するようにして、できるよ
うになりました。

> ライブラリなんて探せばたくさん見つかるだろうと思ったんですが、
> なさげですね。みんなどうやってるんでしょう?

私も色々探してみたのですが、マルチバイトに対応した検索(置換)を
してくれるライブラリは見つかりません。

結構FAQ的な感じもするので、汎用的なライブラリもあると思ったので
すが、皆さん、その都度、自力で組んでるのかな....????

B-Cus 1999/12/23(木) 10:53:18
日本語 locale に対応した UNIX ならこんな感じ。

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

main(){
    wchar_t wbuf[100];
    wchar_t wsearch;
    int i;

    setlocale(LC_ALL,"ja");     /* 他には ja_JP.EUC など。OS依存 */

    mbstowcs(&wsearch,"ス",sizeof wsearch);
    mbstowcs(wbuf,"これはテストです。",sizeof wbuf);
    for ( i=0 ; wbuf[i]!='\0' ; i++ ){
        char tmp[5];
        wctomb(tmp,wbuf[i]);
        printf("%d %s",wbuf[i],tmp);
        if ( wbuf[i] == wsearch ){
            printf(" MATCH!");
        }
        printf("\n");
    }
}

実行結果:
 805311027 こ
 805311084 れ
 805311055 は
 805311174 テ
 805311161 ス MATCH!
 805311176 ト
 805311047 で
 805311033 す
 805310627 。

僕にはここらへんの知識がないので、このコードには
自信がありません。誰か正解を教えて。
# locale って Windows にもあるの?

> 汎用的なライブラリもあると思ったのですが
PTAN さんがライブラリを作って配布する、と :-)

ラウォッチ 1999/12/23(木) 10:55:12
わたしは、2バイト文字(0x80以上)をカウントしていき、
2で割って、漢字の境界を判断しています!

B-Cus 1999/12/23(木) 11:02:23
> わたしは、2バイト文字(0x80以上)をカウントしていき、
SJIS だと半角カナで、EUC だと補助漢字でこけませんか?
# 大丈夫だっけ?

ついでに質問なんですが、なんでそんなに「!」を多用するんですか?
怒っているんですか? 興奮しているんですか?

ラウォッチ 1999/12/23(木) 14:16:45
>SJIS だと半角カナで
UNIX上では変換以外(これもライブラリ使う)SJISの処理はまだした時がありません。(C言語で、しかし、PerlではSJIS主体)

>EUC だと補助漢字でこけませんか?
いままで、意識していません!
明日、会社に行って調べてみます!(手元に資料ない)
ご指摘ありがとうございます。

>なんでそんなに「!」を多用するんですか?
「!」は癖ですか、結構好きです!

いつも、B-Cusさんとふじさんの発言スレッドはかならず見ています。
いつもわかりやす説明ありがとうございます!

きたむら 1999/12/23(木) 15:47:33
Windows(VisualC++)でも最近はlocaleを設定してmbstowcsなどを使うようになっています。
B-Cusさんのサンプルもそのままコンパイル可能です(LC_ALLは"Japanese"に設定)。

ただしVC++のwctombは生成したmb文字列に'\0'を付加しない(?詳細未詳)ため、以下の修正も必要でした。
> wctomb(tmp,wbuf[i]);
> printf("%d %s",wbuf[i],tmp);
 ↓
int len=wctomb(tmp,wbuf[i]); /* VC++ではバイト数を返す */
printf("%d %.*s",wbuf[i],len,tmp);

B-Cus 1999/12/23(木) 17:27:10
> 「!」は癖ですか、結構好きです!
そうですか。「!」が好きなんですか。
  ・日本語として美しくない (句点の出番がないし)
  ・ずっと大声で怒鳴られているような印象を受け、読みにくい
  ・書き手の感情を推し量ることができない
という理由から、もしこだわりがないなら、「!」の多用を
やめていただけないかと思ったのですが、残念です。


補足どうもです>きたむらさん

> Windows(VisualC++)でも
ふーむ、locale って結構ポータビリティあるんですね。知らなかった。

> ただしVC++のwctombは生成したmb文字列に'\0'を付加しない
これは Solaris2.5.1 でも同じでした。上の例は、たまたま 0で
埋まっていただけのようです。

[上に] [前に] [次に]