[前へ]   [目次へ]   [次へ]

文字の扱い(3)(C/C++)

今回は、文字の比較です。

もう察しがついている方もいるかと思いますが、
文字の比較とは、文字コードの比較であり、それは数値の比較です。

'A' のような表記はその文字の文字コードの値の数値定数なので、条件式に与えることができます。
また、 switch の case にも使用することが出来ます。

また、アルファベットの判定などは、文字コードが連続して配置されていることを利用して、
'A' 以上 'Z' 以下等の指定を使用することが出来ます。

<  1>
<  2>
<  3>
<  4>
<  5>
<  6>
<  7>
<  8>
<  9>
< 10>
< 11>
< 12>
< 13>
< 14>
< 15>
< 16>
< 17>
< 18>
< 19>
< 20>
< 21>
< 22>
< 23>
< 24>
< 25>
#include <stdio.h>

int main(void)
{
   
char buf[10]="";
   printf(
"何か一文字入力してください:");
   fgets(buf,5,stdin);
   printf(
"\n入力された文字コード:%d(0x%x)\n",buf[0],buf[0]);//(1)
   
printf("入力された文字:%c\n",buf[0]);
   
if((buf[0]>='0')&&(buf[0]<='9')){//(2)
      
puts("入力された文字は 数字 です。");
   }
   
else if((buf[0]>='A')&&(buf[0]<='Z')){
      puts(
"入力された文字は 大文字アルファベット です。");
   }
   
else if((buf[0]>='a')&&(buf[0]<='z')){
      puts(
"入力された文字は 小文字アルファベット です。");
   }
   
else{
      puts(
"入力された文字は数字でもアルファベットでもありません。");
   }
   
//終了待ち
   
getchar();
   
return 0;

実行例1:
何か一文字入力してください:7

入力された文字コード:55(0x37)
入力された文字:7
入力された文字は 数字 です。

実行例2:
何か一文字入力してください:d

入力された文字コード:100(0x64)
入力された文字:d
入力された文字は 小文字アルファベット です。

実行例3:
何か一文字入力してください:K

入力された文字コード:75(0x4b)
入力された文字:K
入力された文字は 大文字アルファベット です。

実行例4:
何か一文字入力してください:=

入力された文字コード:61(0x3d)
入力された文字:=
入力された文字は数字でもアルファベットでもありません。

実行例5:(単にEnterを入力)
何か一文字入力してください:

入力された文字コード:10(0xa)
入力された文字:

入力された文字は数字でもアルファベットでもありません。

一文字入力すると、その文字の文字コード、文字、分類を返す簡単なプログラムです。

8行目(1)の printf 関数では、初登場の %x 指定を行っています。
%x 指定は引数の数値を16進法で表現して表示します。
%d 指定と %x 指定の違いは10進数として表示するか、16進数として表示するかと、 %x 指定は符号なしという点です。

ここで10行目(2)の条件式を詳しく見てみます。
今回は、実行例1の入力の時を解説します。
A             B  C
(buf[0]>='0') && (buf[0]<='9')


通し記号種別
A複合式
B演算子(&&)(二項、論理、優先5、結合→)
C複合式
今回は、()によって式を一まとめにした複合式があります。

まず、この時点では演算子は演算子B(&&)ひとつしかないので、
演算子B、左辺 複合式A、右辺 複合式Cです。

&&(論理AND)演算子は、左辺と右辺両方の評価結果が真の時、真を返す演算子です。
また、左辺から評価して、左辺が偽だった場合、右辺を評価しません。
右辺で関数を呼び出したり、変数を更新している場合はこの点に注意が必要です。

という訳で、左辺の 複合式Aの真偽ですが、複合式のままでは真偽値として使えないので、
まず、複合式の処理を先に行って、ただの値に置換えます。

複合式A
A   B C B' D  E
buf [ 0 ]  >= '0'


通し記号種別
Achar[10]"7"配列変数(buf)
B演算子( [] )(その他、優先16、結合→)
Cconst int0定数
B'演算子Bの終点
D演算子(>=)(二項、論理、優先10、結合→)
Econst char48定数('0')
注:定数Eの型は C++ の場合。以降も同様。

優先順位から、演算子B( [ ] )、左辺 変数A、右辺 定数Cから処理します。
変数A( buf )から定数Cが示す0番目の要素を返します。

A      B  C
vtemp1 >= '0'


通し記号種別
Achar&55一時変数(buf[0])('7')
B演算子(>=)(二項、論理、優先10、結合→)
Cconst char48定数('0')
次は、演算子B(>=)、左辺 一時変数A、右辺 定数Cの処理です。

>=(以上)演算子は、左辺が右辺以上の時、真を返します。
この例では左辺55、右辺48なので、真が返されます。
この値は複合式の結果として一時変数( vtemp2 )に格納されて最初の式の評価に戻ります。

A      B  C
vtemp2 && (buf[0]<='9')


通し記号種別
Aint1(真)一時変数
B演算子(&&)(二項、論理、優先5、結合→)
C複合式
ここで一時変数Aが偽ならば複合式Cは評価されることなく演算子Bは偽を返します。
しかし今回は一時変数Aは真なので、複合式Cの評価が行われます。

複合式C
A   B C B' D  E
buf [ 0 ]  <= '9'


通し記号種別
Achar[10]"7"配列変数(buf)
B演算子( [] )(その他、優先16、結合→)
Cconst int0定数
B'演算子Bの終点
D演算子(<=)(二項、論理、優先10、結合→)
Econst char57定数('9')

優先順位から、演算子B( [ ] )、左辺 変数A、右辺 定数Cから処理します。
変数A( buf )から定数Cが示す0番目の要素を返します。

A      B  C
vtemp1 <= '9'


通し記号種別
Achar&55一時変数(buf[0])('7')
B演算子(<=)(二項、論理、優先10、結合→)
Cconst char57定数('9')
次は、演算子B(<=)、左辺 一時変数A、右辺 定数Cの処理です。

<=(以下)演算子は、左辺が右辺以下の時、真を返します。
この例では左辺55、右辺57なので、真が返されます。
この値は複合式の結果として一時変数( vtemp3 )に格納されて最初の式の評価に戻ります。

これでようやく演算子Bの評価を完了できます。
A      B  C
vtemp2 && vtemp3


通し記号種別
Aint1(真)一時変数
B演算子(&&)(二項、論理、優先5、結合→)
Cint1(真)一時変数
一時変数A、一時変数C両方が真なので、真が返され、条件式は真になります。
この時、 buf[0] がどちらかの条件を満たせなければ偽になるので、文字の種別を判定することが出来ます。


また、 switch で使用する場合は、以下のようになります。
<  1>
<  2>
<  3>
<  4>
<  5>
<  6>
<  7>
<  8>
<  9>
< 10>
< 11>
< 12>
< 13>
< 14>
< 15>
< 16>
< 17>
< 18>
< 19>
< 20>
#include <stdio.h>

int main(void)
{
   
char buf[10]="B";
   
switch(buf[0]){
   
case 'A':
      puts(
"A");
      
break;
   
case 'B':
      puts(
"B");
      
break;
   
case 'C':
      puts(
"C");
      
break;
   }
   
//終了待ち
   
getchar();
   
return 0;
実行結果:
B

switch に渡す「指定値」の時点で要素を特定しておく点を除けば、特に特別な点はないかと思います。
case に渡すのは数値であればいいので、文字コードの数値である文字はそのまま渡すことが可能です。


次回は、変数の内部表現についてです。

[前へ]   [目次へ]   [次へ]

プログラミング講座 総合目次

最終更新 2008/10/17