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

解決


上野浩二  2005-12-09 00:59:12  No: 59899

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

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

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

windowsXP VC++ MFC


Blue  2005-12-09 01:18:47  No: 59900

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

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

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


dairygoods  2005-12-09 01:47:28  No: 59901

_ismbbkana で調べられます。


Blue  2005-12-09 01:54:43  No: 59902

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


上野  2005-12-13 03:43:35  No: 59903

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

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

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

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

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


Blue  2005-12-13 08:33:13  No: 59904

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

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

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

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


Blue  2005-12-13 08:45:59  No: 59905

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

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


dairygoods  2005-12-13 19:40:11  No: 59906

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

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 19:54:06  No: 59907

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

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

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


上野  2005-12-13 20:37:15  No: 59908

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

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


Blue  2005-12-13 20:42:42  No: 59909

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 21:58:42  No: 59910

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

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

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

とかが良いかも。


上野  2005-12-13 22:14:27  No: 59911

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

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 22:23:21  No: 59912

> 戻り値が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 22:25:21  No: 59913

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

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


上野  2005-12-13 23:20:24  No: 59914

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


Blue  2005-12-13 23:30:29  No: 59915

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

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


Blue  2005-12-13 23:31:57  No: 59916

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

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


上野  2005-12-13 23:41:37  No: 59917

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


Blue  2005-12-13 23:47:29  No: 59918

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

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

Shift_JISコード文字列

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

ヤレヤレ┐(´ー` )┌


上野  2005-12-13 23:51:15  No: 59919

あ…あぁ…orz

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


Blue  2005-12-13 23:52:24  No: 59920

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

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

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

以上。


上野  2005-12-14 00:02:33  No: 59921

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

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


dairygoods  2005-12-14 00:03:55  No: 59922

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

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


上野  2005-12-14 03:21:38  No: 59923

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

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

以上です。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加