![見出し画像](https://assets.st-note.com/production/uploads/images/94451624/rectangle_large_type_2_304ee4241ff7366c9b12a07bfd505c37.png?width=1200)
C言語教室 第10回 - 文字種判定と文字コード
さて2023年も始まりました。今年もよろしくお願いします。まだお正月気分が抜けきれていないのではないかと思いますし、軽めの内容からはじめます。
C言語で扱う文字は、その文字コードは規定されていないのですが、普通はASCIIコードが仮定されています。もちろんASCIIに準拠していればJIS X 0201(1バイト文字を対象としたJIS規格)などいろいろな国で拡張されたコードであっても使えるように配慮されています。厳密にはロケールと呼ばれる設定の影響を受けるのですが、ここでは標準ロケールであるCロケールを前提とし、マルチバイト文字については考えないことにします。
ASCIIの範囲でも画面に表示される文字や表示されないが特別な意味を持つ制御文字、表示される文字であっても数字なのかアルファベットの大文字や小文字などの種類があります。これらを文字リテラルやコードを直接使ってハードコードしてしまうこともシバシバなのですが、標準関数として用意されているものがいくつかあります。
これら文字種判定の関数を使う際には、ctype.hをインクルードします。ここにある関数は引き数で渡す文字の型が int になっているのですが、このおかげで0x80~0xFFの1バイト文字も符号の影響を受けずに処理ができるようになっています。とはいえマルチバイト文字を渡した時の結果は未定義です。
int isalnum(int c);
英数字('A'~'Z', 'a'~'z', '0'~'9')なら真(0以外の値)を返す。int isalpha(int c);
英文字('A'~'Z', 'a'~'z')なら真(0以外の値)を返す。int isblank(int c);
標準ブランク文字(' ', "\t")なら真(0以外の値)を返す。int iscntrl(int c);
制御文字(0x00~0x1f, 0x7f)なら真(0以外の値)を返す。int isdigit(int c);
数字('0'~'9')なら真(0以外の値)を返す。int isgraph(int c);
空白(' ')を除く表示文字(0x21~0x7e)なら真(0以外の値)を返す。int islower(int c);
英小文字('a'~'z')なら真(0以外の値)を返す。int isprint(int c);
空白(' ')を含む表示文字(0x20~0x7e)なら真(0以外の値)を返す。int ispunct(int c);
区切り文字(0x21~0x2f, 0x3a~0x40, 0x5b~0x60, 0x7b~0x7e)なら真(0以外の値)を返す。int isspace(int c);
標準空白類文字(' ', '\f', '\n', '\r', '\t', '\v')なら真(0以外の値)を返す。int isupper(int c);
英大文字('A'~'Z')なら真(0以外の値)を返す。int isxdigit(int c);
16進数字('0'~'9', 'A'~'F', 'a'~'f')なら真(0以外の値)を返す。int tolower(int c);
文字cを小文字に変換した値を返す。int toupper(int c);
文字cを大文字に変換した値を返す。
表示する際に書式が乱れないように制御文字を出さないように isprint を使ったり、検索に先立って大文字小文字を区別しないようにするために toupper (または tolower) で文字を加工したりするのに使います。こららを使わずにif文を書いてしまいがちですが、きちんとロケール(これが危険な場合もありますが)を考慮してくれますし、実体は関数呼び出しではなくマクロで、しかもコードの大小判定ではなくより効率的な表引きで実装されていたりするので、できるだけライブラリ関数を使うのがオススメです。0x7fが制御文字であることを忘れがちですしね。なにより関数名で処理の意図が明確になることが大切です。
課題
呼び出し側で用意した文字列に含まれる英小文字をすべて英大文字に書き換える関数を書きなさい。
演習
渡された文字列に表示文字以外が含まれる時、それらの文字を”\x”で始まる16進コードの文字列に変換する関数を書きなさい。なお表示文字列でも”\”に関しては”\\”に変換する。変換後の文字列領域は関数を呼び出す側で用意しても関数で動的に確保しても良い。変換後の文字列を格納する領域は最大でも元の文字列の4倍までであることは仮定しても良い。
今回は、少し発展的な課題を演習として別にしてみました。締切はありませんので、ご自分のペースで取り組んでいただければと思います。答え合わせは、なるべく次回までには用意したいのですが、間に合わなかったらゴメンナサイ。
C言語/標準ライブラリ/ctype.h
標準Cライブラリの実装
ヘッダ画像は、以下のものを使わせて頂きました。
https://commons.wikimedia.org/wiki/File:USASCII_code_chart.png
いいなと思ったら応援しよう!
![kzn](https://assets.st-note.com/production/uploads/images/111925158/profile_dffba6e25229ee04f46397fb91bbfc20.jpg?width=600&crop=1:1,smart)