• ベストアンサー

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がでて処理もうまくいきません。 よい方法を教えていただけないでしょうか? よろしくお願いします。

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

  • ベストアンサー
  • s2t
  • ベストアンサー率79% (47/59)
回答No.4

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で動作確認しましたが、きちんと検証していないので間違っている可能性があります。

hidekin
質問者

お礼

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

その他の回答 (3)

  • s2t
  • ベストアンサー率79% (47/59)
回答No.3

恐らく表示されるワーニングは、「演算子の優先順位に問題があります」ってヤツじゃないですか? ANo.#1の方の回答で解決すると思います。 しかしながら、この条件式には問題があります。 残念ながら、この条件ではEUC-JPの漢字第1バイトと判定できないと思われます。 EUC-JPは1バイト目と2バイト目が 0xa1a1 - 0xfefe と同一の範囲です。 また、半角カナが含まれる場合は 0x8ea1 - 0x8edf となり、JIS X 0212、JIS X 0213が含まれる場合は 0x8fa1a1 - 0x8ffefe という3バイトコードになります。 なので、判定するには最低でも後ろから2バイトはチェックする必要があるのでは?

hidekin
質問者

補足

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

  • ranx
  • ベストアンサー率24% (357/1463)
回答No.2

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

hidekin
質問者

お礼

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

  • yotta
  • ベストアンサー率32% (26/79)
回答No.1

括弧が足らないのでは? if((work[19] >= 0xa1 && work[19] <= 0xdd) || (work[19] >= 0xdf && work[19] <= 0xfe)){ としてコンパイルしてみて下さい.

hidekin
質問者

お礼

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

関連するQ&A