みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

EUCの漢字第1バイトを判定する

EUCの文字列の最終文字が漢字第1バイトであるかを判定
したいのですが・・・・。

char work[21];
.
.
memcpy(work, &buf[0], 20);
if(work[19] >= 0xa1 && work[19] <= 0xdd ||
work[19] >= 0xdf && work[19] <= 0xfe){
.
.
このようなコードでworkにコピーした文字列の最後の文字が
漢字第1バイトか判定しています。
しかし、コンパイルではwaningがでて処理もうまくいきません。

よい方法を教えていただけないでしょうか?
よろしくお願いします。

投稿日時 - 2002-08-08 16:52:04

QNo.331779

すぐに回答ほしいです

質問者が選んだベストアンサー

Shift_JISで処理するのはダメですか?
EUC_JPでやる場合は、頭からカウントしてやらないと第1バイトなのか第2バイトなのか判断が難しいです。

Shift_JISで良いのなら

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

#define MAXBUFSIZE 20

#define ascii(c)((c)<=0x7e)
#define kana(c)((c)>=0xa1 && (c)<=0xdf)
#define sjis_u(c)(((c)>=0x81 && (c)<=0x9f) || ((c)>=0xe0 && (c)<=0xfc))
#define sjis_l(c)((c)>=0x40 && (c)<=0xfc && (c)!=0x7f)

int main(int argc, char *argv[])
{
char *buf = "0漢字コード判定のサンプルデータ";
char work[MAXBUFSIZE+1] = {0};
memcpy(work, buf, MAXBUFSIZE);

unsigned char *p = (unsigned char*)(work+MAXBUFSIZE-1);

if(((ascii(*p) || kana(*p)) && !sjis_u(*(p-1))) || (sjis_l(*p) && sjis_u(*(p-1))))
{
printf("正常\n");
}
else
{
printf("異常\n");
}

return 0;
}

こんな感じでどうでしょうか?
一応、MinGWで動作確認しましたが、きちんと検証していないので間違っている可能性があります。

投稿日時 - 2002-08-09 02:53:05

お礼

ありがとうございました。
無事解決しました。また何かありましたらお願いします。

投稿日時 - 2002-08-09 21:29:30

ANo.4

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.3

s2t

恐らく表示されるワーニングは、「演算子の優先順位に問題があります」ってヤツじゃないですか?
ANo.#1の方の回答で解決すると思います。

しかしながら、この条件式には問題があります。
残念ながら、この条件ではEUC-JPの漢字第1バイトと判定できないと思われます。

EUC-JPは1バイト目と2バイト目が 0xa1a1 - 0xfefe と同一の範囲です。
また、半角カナが含まれる場合は 0x8ea1 - 0x8edf となり、JIS X 0212、JIS X 0213が含まれる場合は 0x8fa1a1 - 0x8ffefe という3バイトコードになります。

なので、判定するには最低でも後ろから2バイトはチェックする必要があるのでは?

投稿日時 - 2002-08-09 00:02:44

補足

ご解答ありがとうございます。
そうなんですよ、うまくいかなくていろいろ調べていくうちに
同一の範囲にあるので、1バイトでは判定できないことがわかりました。
この処理ではs-jisのファイルをeucに変換してから行う処理なので
s-jisファイルに半角カナ文字があるとeucでは2バイトで見てしまうため
文字化けを起こしてしまうという問題が発生しました。
最近コボラーからC言語に転身して、1ヶ月はじめての壁で困っています。
何か、よい手はありませんか?
情報あればお願いします。

投稿日時 - 2002-08-09 01:00:50

ANo.2

char型では最上位ビットが立っているとマイナスの値と見なされますからね。
正の値と比較してもうまくいかないんじゃないかな。
0xa1を(char)0xa1とするとか、配列を宣言する際にunsigned charにしておくとか。
質問する時は、warningの内容はきちんと書きましょう。

投稿日時 - 2002-08-08 18:32:34

お礼

助言ありがとうございます。
コンパイルうまくいきました。
これからは、内容もきちんと書くようにします。
これから、もう一度、処理自体を見直さないと・・・。

投稿日時 - 2002-08-09 00:59:53

ANo.1

括弧が足らないのでは?

if((work[19] >= 0xa1 && work[19] <= 0xdd) ||
(work[19] >= 0xdf && work[19] <= 0xfe)){

としてコンパイルしてみて下さい.

投稿日時 - 2002-08-08 17:57:05

お礼

ご解答ありがとうございました。
コンパイルは通りました。処理はうまくいかないのですが・・・。
処理自体間違っているようです。

投稿日時 - 2002-08-09 00:58:11

あなたにオススメの質問