• ベストアンサー

漢字の第1バイト検証

今、文字判定関数について勉強しているのですが、 unsingned char uch にgetchar()の値を入れ if(uch >= 0x81 && uch <= 0x9f || uch >= 0xe0 && uch <= 0xfc) とうコードで、なぜ漢字コードは「0x81~0x9f」と「0xe0~0xfc」の 二つの範囲があるのか解りません。 よろしくお願いします。

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

  • ベストアンサー
noname#25358
noname#25358
回答No.1

 厳密にはそのプログラムは誤りで、 if(uch >= 0x81 && uch <= 0x9f || uch >= 0xe0 && uch <= 0xef)  が正解です。  で、どうして領域が2つに分かれてるかというと、端的にいうと、しょうがなかったからです。  MrSIMPSOM さんが今取得しようとしているのは、シフトJIS形式と呼ばれる文字形式です。  この形式は、半角文字と全角文字を1つの文字列の中に混在させるための手段として、「特定のコードであれば、あとに続く1バイトとの合計2バイトで漢字を表す」としています。  ところが、「では実際にどのコードが来たら漢字ということにするか」ということになった際に、当時まだ使われてなかった領域が、その範囲しかなかったわけです。  当時のコンピュータの性能からして、半角カタカナの領域を潰すわけにはいかなかったからです。  なので、しょうがなく漢字を表す領域は2つに分けられることになってしまったのです。

MrSIMPSOM
質問者

お礼

コードミスしてしまうとは、お恥ずかしい(笑) なるほど、しょうがなく分けられたんですか。 ありがとうございました。

MrSIMPSOM
質問者

補足

補足と言うわけではないのですが、文字コードの2バイト目は、 0x40で始まるじゃないですか、単に0x40は@を表しますよね。 そこで、なんで2バイト目はそこから始まるようになったのですか。 度々すみませんがお願いします。

その他の回答 (1)

noname#25358
noname#25358
回答No.2

 えーと。再登場。  2バイト目についてですが、よく分かりません(^_^;  少なくとも、コントロールコードを回避して配置されたことは確かだと思いますが……。

MrSIMPSOM
質問者

お礼

そうですか...私もコントロールコードは 回避する必要があったとは思いましたが、 別に0x30でもいいじゃん(笑)と疑問に思い補足してみました。 いつのまにかにプログラミングの質問から離れていった質問に 答えてくれてdeagleさんありがとう御座いました。

関連するQ&A

  • シフトJIS の1バイト目

    シフトJISの1バイト目は 0x81~0x9F と 0xE0~0xEF というサイトもある。 0x81~0x9F と 0xE0~0xFC というサイトもある。 最近、文字コードに追加か削除された文字があるから 意見が2つに分かれていると思うんだけど、 現在はどうなのか教えてください。 シフトJISの2バイト目は 0x40~0x7E と 0x80~0xFC ですか? http://google.yahoo.co.jp/bin/query?p=%a5%b7%a5%d5%a5%c8JIS+9F+E0+81&hc=0&hs=0 を参考にしました。

    • 締切済み
    • CGI
  • シフトJIS 2バイト字の範囲

    シフトJISの2バイト文字の範囲は 0x40~0x7e と 0x80~0xfc と 0x40~0xfc のどっちですか? どちらの情報も見たことがあるんです。 シフトJISの文字をマッチングさせる場合、 ここでは見やすく、スペースを入れて / [\x81-\x9f] [\x40-\xfc] | [\xe0-\xfc] [\x40-\xfc] / とした場合、例えば、亜a という文字列があったら 亜 の2バイト目(下位ニブルっていうのかな)が 9F で b は16進で 62 だから、亜 の2バイト目と a が、 2バイトのシフトJISとしてこれにマッチしてしまうんです。 シフトJISで、こういう例外処理を書かずに、 全てに適用できるシフトJIS2バイトマッチのソースが あれば教えてください。

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

  • Shift_JIS漢字を削除したい

    Shift_JISファイルの中の漢字を削除したいですが、 以下のスクリプトがうまく行きません(なにも削除してくれない)。 while ( <IN> ) { chomp(); tr/[\x81-\x9F][\x40-\xFC]//; tr/[\xE0-\xEF][\x40-\xFC]//; print OUT "$_\n"; } どう書けばよいでしょうか?

  • 全角文字を含んだ文字の並びを逆順にするには?

    こんにちは。 C言語において、以下のような2つの関数を利用して、全角文字を含んだ文字列の並びを逆順にする事を考えました。 ちなみにコンパイラは、borlandのC++コンパイラを使っています。 文字コードがShift_JISの場合、全角文字の上位バイトが0x81~0x9F、0xE0~0xFCの範囲に収まるという事を聞いたので、まず、以下のように、渡された文字が、全角文字の上位バイトかどうかを判定する関数を作りました。 ____________________________________________________________ int is_2byte(unsigned char c){ return ( ( (c >= 0x81) && (c <= 0x9f) ) || ( (c >= 0xe0) && (c <= 0xfc) ) ); } ____________________________________________________________ 次に、上の関数を利用し、以下のように、渡された文字列の、文字の並びを逆順にする関数を作りました。 ____________________________________________________________ void rev_str(char *str) { char temp[1000]; char tmp; int i, j; for(i=strlen(str)-1, j=0; i>=0; i--, j++){ temp[j]=str[i]; if(is_2byte(temp[j])){ tmp=temp[j-1]; temp[j-1]=temp[j]; temp[j]=tmp; } } temp[j]='\0'; strcpy(str, temp); } __________________________________________________ この関数を、あいうえお順に試して行った所、ひらがなの 「あいうえお かきくけこ さしすせそ たちつてと なにぬねの はひふへほ まみむめ」 という文字列は、逆順にする事ができたのできました。 しかし、「も」以降の文字を含ませた途端、実行時エラーが発生し、プログラムがストップしてしまいます。 また、カタカナの場合は、「メ」以降の文字を含ませた場合に、実行時エラーとなります。 何が問題なのかが全然分からないので、困っています。 何かいい方法を知っておられる方がいらっしゃれば、是非アドバイスを頂きたいと思います。 では、よろしくお願い致します。

  • シフトJISの2バイト文字

    シフトJISの1バイト目は シフトJISの1バイト目は 0x81~0x9F と 0xE0~0xEF と書いてあるサイトもいくつかあるし、 0x81~0x9F と 0xE0~0xFC と書いてあるサイトもいくつかあります。 どうして意見が2つに分かれているんですか? どっちが正しいのか教えてください。 シフトJISの2バイト目は 0x40~0x7E と 0x80~0xFC ですか?

  • JISの全角判定処理について

    お世話になっております。 C++初心者です。 今、JISの全角判定処理を作っているのですが、 フォームのイベントでKeyPressに関数をセットしてあるのですが、 関数のフォーマットが void *********(char &Key); ※[*]は任意の文字列 になっており、半角ならこの関数を1回通り、 全角なら2回通ります。(引数の変更はできません) そこで下記のような関数を作成しました。 void pressKeyFullPitch(char &Key){   static bool fullFlag = false;   if(fullFlag){     fullFlag=false;     Key='*'     return;   }   if( Key >= 0x81 && Key <= 0x9f) || (Key >= 0xe0 && Key <= 0xfc ){     fullFlag = true;     Key = '*';   }      } 全角で入力された2byte文字は2byteとも[*]にするようにしています。 ここて関数内にstatic boolを宣言していますが、 static変数は関数終了時にも値を保持しているため あまり使わないほうがいい気がするので質問させていただきます。 ※すいません、経験が少ないのでstatic変数について知識が足りないかもしれません。 この場合、static変数を使わずうまく処理できる方法が ありましたら、お願いします。

  • 文字の並び替え

    今、全角文字と半角文字が混在した文字列の並び替えをしています。 また、皆様のお力をおかしください。 例:CBABD → ABBCD 色々調べて以下の関数を使うことはわかったのですが、これをどう使えば、並び替えることが出来るのかがわかりません。教えてください。 例があれば、とてもうれしいのですが・・・ int ZenkakuHantei(unsigned char c) { return (((c >= 0x81) && (c <= 0x9f)) || ((c >= 0xe0) && (c <= 0xfc))); }

  • エクセルの漢字コードを教えてください

    漢字コードから、RANDBETWEEN関数を使って漢字をランダムに表示させたい。 CHAR関数を使って亜と和のコードを調べたら12321と20307だと分かったが、 この間にブランクがかなりあるみたいで、RANDBETWEEN関数でコードを指定しても エラー表示になる場合が多い。 漢字コードが一覧表になっているのがあれば一番いのですが。 よろしくお願いします。

  • UTF-8(日本語)の自動判別

    VC++6.0で日本語(漢字)を処理するプログラムを作成しています。 以下のサイトを参考にして、下記 KanjiCode()関数にUTF-8の判別条件を入れたいのですが、判別のアルゴリズムとcodeの書き方がよくわかりません。 参考になるサイトか、アドバイスがあればよろしくお願いします。 出典: http://www-cms.phys.s.u-tokyo.ac.jp/~naoki/CIPINTRO/CCGI/kanjicod.html -------------------------------------------------------------------- #define ASCII 0x00 #define EUC 0x01 #define SJIS 0x02 #define JIS 0x04 #define UTF8 0x05 #define JAPANESE 0xff //---- 半角カナの存在を無視した漢字コードの判定関数 int KanjiCode( char* text ) { for( u_char* ptr=(u_char*)text; *ptr; ptr++ ){ if( *ptr == 0x1b && *(ptr+1) == '$' ) return JIS; if( *ptr < 0x80 ) continue; if( 0x81 <= *ptr && *ptr <= 0x9F ) return SJIS; if( 0xA1 <= *ptr && *ptr <= 0xDF ) return EUC; if( *(ptr+1) <= 0xA0 ) return SJIS; if( /* ここにutf-8 の判別条件を入れたい */ ) return UTF8; } return ASCII; } -------------------------------------------------------------------- UTF-8の自動判別が出来れば文字コード変換は、WindowsであればMultiByteToWideChar/WideCharToMultiByteでなんとかなると考えています。 よろしくお願いします。