カタカナの半角と全角を区別するには?

解決


上野浩二  2005-12-08 15:59:12  No: 59899  IP: 192.*.*.*

はじめまして、上野と申します。

質問なのですが、文字列内に半角のカタカナが入っているかどうかを
調べたいのですが、どうすればいいのでしょうか?
(半角英数字は許可/半角カタカナは禁止(エラー表示)としたい)

よろしくおねがいいたします。

windowsXP VC++ MFC

編集 削除
Blue  2005-12-08 16:18:47  No: 59900  IP: 192.*.*.*

文字コードで判定すればいいでしょう。

char型配列で文字列を持っている(CStringでプロジェクトが_MBCSであるならば)
Shift_JISコードになるので、半角カタカナのコードで判定すればいいです。
(文字を取り出すときは全角かどうか判定しないといけないですが、)

また、半角カタカナ一覧テーブルを作って、そこにない場合はOKとかにしてもいいと思います。

編集 削除
dairygoods  2005-12-08 16:47:28  No: 59901  IP: 192.*.*.*

_ismbbkana で調べられます。

編集 削除
Blue  2005-12-08 16:54:43  No: 59902  IP: 192.*.*.*

> _ismbbkana で調べられます。
あ、そんなのあったんですね。
でも、全角判定はしないといけなそうですけど。(_ismbblead)

編集 削除
上野  2005-12-12 18:43:35  No: 59903  IP: 192.*.*.*

返信遅くなりましてすみません。

今現在やりたいのはボタン押下時の処理なのですが、
・ボタン押下↓
・EditBoxに入力された文字を取得(CString型の変数に取得)↓
・取得した文字を1文字ずつ見ていく↓
・「半角カナ・ひらがな」があった場合はメッセージボックス表示

というものを作成したいのですが、_ismbbkanaを検索しても、
サンプルなどが見つからず困っています。

一応_ismbbkanaを使って処理を作成してみたのですが、
半角カナの場合でも0で返ってきてしまっている状態です。


もう少し自分でも調べてみますが、
もし参考サイト様などご存知でしたらご教授くださいますようお願いいたします。

編集 削除
Blue  2005-12-12 23:33:13  No: 59904  IP: 192.*.*.*

> 一応_ismbbkanaを使って処理を作成してみたのですが、
> 半角カナの場合でも0で返ってきてしまっている状態です。
ここのソースを載せたほうが的確なアドバイスができると思います。

個人的には、チェック用関数をつくってあげて、戻り値で判定するようなつくりにします。

bool CheckKana( const CString data )
{
    LPCTSTR p = data;

    /* 文字列の終わりまで */
    while ( *p )
    {
        if ( 半角カタカナである場合 )
        {
            return false;
        }
        /* 全角だったら、2文字分、
           半角だったら、1文字分ポインタを進める */
        ???????
    }
    /* ここまでくると正常 */
    return true;
}

編集 削除
Blue  2005-12-12 23:45:59  No: 59905  IP: 192.*.*.*

> ・「半角カナ・ひらがな」があった場合はメッセージボックス表示
ひらがなもあったのね。。。
漢字とか全角英字とか全角カタカナはOKなのかな?

全角ひらがなを判定するには、それ用の関数はおそらく用意されていません。
文字コードで判定することになると思います。

編集 削除
dairygoods  2005-12-13 10:40:11  No: 59906  IP: 192.*.*.*

連続で横からすんません。

for (unsigned char* p = text; *p; p = _mbsinc(p)) {
  unsigned int c = _mbsnextc(p);
  if (c < 0xff && _ismbbkana(c)) {
    // 半角カナ
  }
  else if (_ismbchira(c)) {
    // 全角ひらがな
  }
  else if (_ismbckata(c)) {
    // 全角カタカナ
  }
}

_ismbb*, _ismbc* というのを見てみると
意外といろんな種類が調べられることが分かりますよ。

編集 削除
Blue  2005-12-13 10:54:06  No: 59907  IP: 192.*.*.*

mbstring.hを使わないでもいけるかなと思ったので、
_mbsincの存在は知っていましたが、あえて_ismbbleadで全角判定といっていたのですが、

_mbsnextcの存在は知らなかったです。
# いちいち、全角判定して、MAKEWORDしてた。。(´△` )アー

当然、_ismbchira,_ismbckataも知るわけもなく、
文字コードテーブル作って、下位バイトで判定していた罠。

編集 削除
上野  2005-12-13 11:37:15  No: 59908  IP: 192.*.*.*

Blueさん、dairygoodsさん、ありがとうございます。
Blueさんとdairygoodsさんから教えていただいたサンプルを元に
コーディング中なのですが、
dairygoodsさんのサンプルの中にある
>for (unsigned char* p = text; *p; p = _mbsinc(p))
という処理のtextという変数は何型なのでしょうか?
CStringの変数を入れてみたところ、
「CStringからunsigned char*に変換できません」というエラーがでてしまいました。

何か他の型に変換してからじゃないといけないのでしょうか?

編集 削除
Blue  2005-12-13 11:42:42  No: 59909  IP: 192.*.*.*

CStringには LPCTSTR 用のキャスト用Operatorしかありません。

CString s( "1234" );
LPCTSTR p = s;

はできますが、

CString s( "1234" );
unsigned char* p = s;

はできないのは当然です。

でどうすればいいかというと
LPCTSTR(char*のtpyedef(ただし_MBCSのみ))からunsigned char* にキャストしてあげればいいです。

よって、

CString s( "1234" );
unsigned char* p = ( unsigned char* )( ( LPCTSTR )s );

編集 削除
dairygoods  2005-12-13 12:58:42  No: 59910  IP: 192.*.*.*

const に真面目に付き合うと、

// Windows風 typedef
typedef const unsigned char* LPCMBSTR;

for (LPCMBSTR p = (LPCMBSTR)(LPCSTR)s; ...) {

とかが良いかも。

編集 削除
上野  2005-12-13 13:14:27  No: 59911  IP: 192.*.*.*

アドバイスありがとうございます;_;

LPCTSTR p = str;
for (unsigned char* us = ( unsigned char* )p; *us; us = _mbsinc(us)) {
    unsigned int c = _mbsnextc(us);
    if (c < 0xff && _ismbbkana(c)) {
  // 半角カナの処理
         // メッセージボックス表示
    }
}

という処理になっているのですが、やはり半角カタカナの場合、
戻り値が0になっています…
全角カタカナだと戻り値が1…
なので、現状は、全角カタカナの場合のみ、メッセージボックスがでます…

どこかおかしな箇所ありますでしょうか??

編集 削除
Blue  2005-12-13 13:23:21  No: 59912  IP: 192.*.*.*

> 戻り値が0になっています…
って、ドコに戻り値ありますか?(return文)


typedef const unsigned char* LPCMBSTR;

#define LPCMBSTR_CAST( s ) ( ( LPCMBSTR )( ( LPCSTR )s ) )

/////////////////////////////

bool CheckStr( const CString data )
{
    for ( LPCMBSTR = LPCMBSTR_CAST( data ); *p; p = _mbsinc( p ) )
    {
        unsigned int c = _mbsnextc( p );
        if ( c < 0xff && _ismbbkana( c ) ) return false;    /* 半角カタカナ */
        if ( _ismbchira( c ) )             return false;    /* 全角ひらがな */
        if ( _ismbckata( c ) )             return false;    /* 全角カタカナ */
    }
    return true;
}

/////////////////////////////

CString s = "ABCカタカナ";
if ( !CheckStr( s ) )
{
    AfxMessageBox( "エラー" );
}
else
{
    ・・・・・
}

編集 削除
Blue  2005-12-13 13:25:21  No: 59913  IP: 192.*.*.*

>     for ( LPCMBSTR = LPCMBSTR_CAST( data ); *p; p = _mbsinc( p ) )
pが抜けてました。
for ( LPCMBSTR p = LPCMBSTR_CAST( data ); *p; p = _mbsinc( p ) )

コンパイル通していないから、エラーがでたら臨機応変に対応してください。

編集 削除
上野  2005-12-13 14:20:24  No: 59914  IP: 192.*.*.*

どうやら、_ismbbkanaはマルチバイトにしか対応してないみたいですね…

編集 削除
Blue  2005-12-13 14:30:29  No: 59915  IP: 192.*.*.*

> どうやら、_ismbbkanaはマルチバイトにしか対応してないみたいですね…
え?

どっからその結論になったのでしょうか?
入力文字列は Sfit_JIS ですよね?

編集 削除
Blue  2005-12-13 14:31:57  No: 59916  IP: 192.*.*.*

> 入力文字列は Sfit_JIS ですよね?
Shift_JISでした。

試しにやってみたら、
ちゃんと "ハンカク" はMessageBox がでますよ。
どのような文字列を判定しようとしているのでしょうか?

編集 削除
上野  2005-12-13 14:41:37  No: 59917  IP: 192.*.*.*

当方UNICODEと使っていたのですが、
UNICODEに対応しているものを使わなければいけないみたいで…
(人に聞いただけですが…)

編集 削除
Blue  2005-12-13 14:47:29  No: 59918  IP: 192.*.*.*

> char型配列で文字列を持っている(CStringでプロジェクトが_MBCSであるならば)
一番最初に聞いたつもりですが?

char型配列で文字列を持っている

Shift_JISコード文字列

UNICODE文字列ではない=wchar_t型配列でない=CStringでプロジェクトが_UNICODEになっている

ヤレヤレ┐(´ー` )┌

編集 削除
上野  2005-12-13 14:51:15  No: 59919  IP: 192.*.*.*

あ…あぁ…orz

ほんとすみません。。。;_;

編集 削除
Blue  2005-12-13 14:52:24  No: 59920  IP: 192.*.*.*

> CStringでプロジェクトが_UNICODEになっている
じゃなくて
CStringでプロジェクトが_UNICODEになっていない
でした。

結局 _mbs〜 はなんのライブラリなのか分からず使っていたのが問題ですね。
MSDNに思いっきりコードページ932ってかいてあるんですけど。

解答する気が一気になくなったので、一番楽な解決法だけ紹介します。
Unicode文字列をShift_JISに変換して判定してください。

以上。

編集 削除
上野  2005-12-13 15:02:33  No: 59921  IP: 192.*.*.*

>Unicode文字列をShift_JISに変換して判定してください。
これだけはさけたいのでなんとか自力で頑張ります。

ありがとうございました。
そしてご迷惑おかけいたしました。

編集 削除
dairygoods  2005-12-13 15:03:55  No: 59922  IP: 192.*.*.*

UNICODE については、GetStringTypeW で調べられそうな感じです。

http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/resources/strings/stringreference/stringfunctions/getstringtypeex.asp

編集 削除
上野  2005-12-13 18:21:38  No: 59923  IP: 192.*.*.*

たびたびすみせん。(質問ではないです)

結局、1文字ずつ文字コードと比較することにしました。
処理はまだ作成しておりませんが、これから比較方法など調べていこうと思います。

以上です。

編集 削除