C言語で文字を扱うとき、英字か数字か、それともそれ以外かを判定できると入力チェックやバリデーションにとても役立ちます。
本記事ではC言語標準ライブラリのctype.hを使って、アルファベット・数字・その他の文字を判定する方法を、初心者向けに丁寧に解説します。
基本的な仕組みから実践的なサンプルプログラムまで順に見ていきます。
文字判定の基本
C言語における文字判定とは
C言語では、文字はchar型で表現されます。
プログラムを書いていると、次のような場面で「文字判定」が必要になります。
- 入力された文字が英字かどうかを確かめたいとき
- パスワードが英数字だけで構成されているか確認したいとき
- 数字が入力されたかどうかを判定したいとき
文字判定とは、char型の値を調べて、それが「英字」「数字」「空白」「記号」など、どの種類に分類されるかを判定する処理のことです。
C言語では、このような判定を自力で行うこともできますが、ASCIIコードの値を1つ1つ比較するのは面倒ですし、ミスもしやすくなります。
そこで、標準ライブラリであるctype.hを利用する方法がよく使われます。
ctype.hでできること
ctype.hは、文字の分類や変換を行うための標準ライブラリです。
代表的な関数をいくつか挙げると、次のようになります。
| 関数名 | 役割 |
|---|---|
isalpha | 英字(アルファベット)かどうかを判定 |
isdigit | 数字(0〜9)かどうかを判定 |
isalnum | 英字または数字かどうかを判定 |
isspace | 空白文字(スペースや改行など)かどうかを判定 |
islower | 小文字かどうかを判定 |
isupper | 大文字かどうかを判定 |
tolower | 文字を小文字に変換 |
toupper | 文字を大文字に変換 |
これらの関数を使うと、文字コードを直接意識せずに、「意味」で判定や変換ができるようになります。
ctype.hを使うときは、プログラムの先頭付近で次のようにインクルードします。
#include <ctype.h>
文字コード(char型)とASCIIの関係
C言語のchar型は、内部的には整数の一種です。
実際には、コンピュータ内部では文字も数値(文字コード)で表現されています。
代表的な文字コードとしてASCIIがあります。
ASCIIでは、次のような対応が決まっています。
| 文字 | 意味 | ASCIIコード(10進) |
|---|---|---|
| ‘0’ | 数字の0 | 48 |
| ‘9’ | 数字の9 | 57 |
| ‘A’ | 英大文字A | 65 |
| ‘Z’ | 英大文字Z | 90 |
| ‘a’ | 英小文字a | 97 |
| ‘z’ | 英小文字z | 122 |
ASCIIでは、数字や英字は連続した番号で定義されています。
そのため、次のような判定も可能です。
- 数字かどうか:
'0' <= c && c <= '9' - 英大文字かどうか:
'A' <= c && c <= 'Z' - 英小文字かどうか:
'a' <= c && c <= 'z'
しかし、ASCII以外の文字コード(ロケール)や環境の違いを考えると、このような直接比較は安全とは限りません。
そのため、移植性や可読性の観点からctype.hの関数を使うのが推奨されます。
isalphaでアルファベット判定する方法
isalphaの基本仕様と戻り値
isalphaは、引数の文字が英字(アルファベット)かどうかを判定する関数です。
ヘッダctype.hで定義されています。
関数の宣言は、概ね次のようになっています。
int isalpha(int c);
主な仕様は次の通りです。
- 引数
cに、判定したい文字を渡します。 cが英字(英大文字または英小文字)なら、0以外の値を返します。- 英字でない場合は、0を返します。
- 戻り値が「0かどうか」で真偽判定に使うのが一般的です。
戻り値が「0以外ならtrue」とみなせるのがポイントです。
戻り値の具体的な数値(1や2など)には依存しないようにします。
英大文字・英小文字の両方を判定する書き方
isalphaは、英大文字(A〜Z)と英小文字(a〜z)の両方を自動で判定してくれます。
自分で大文字と小文字を別々に判定する必要はありません。
自力で書くと次のような条件分岐になります。
if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')) {
/* 英字 */
}
これをisalphaを使うと、次のように簡潔に書けます。
if (isalpha((unsigned char)c)) {
/* 英字 */
}
引数は(unsigned char)にキャストして渡すのが推奨されています。
これは、環境によってcharが符号付きになる場合があるためです。
初心者のうちは、「isalphaの引数には(unsigned char)を付ける」と覚えておくと安全です。
if文と組み合わせたアルファベット判定サンプル
実際にisalphaを使って、1文字が英字かどうかを判定するサンプルを見てみます。
#include <stdio.h>
#include <ctype.h>
int main(void) {
char ch;
printf("1文字入力してください: ");
scanf(" %c", &ch); // 先頭にスペースを入れて前の改行を読み飛ばす
// isalphaで英字かどうかを判定
if (isalpha((unsigned char)ch)) {
printf("'%c' は英字です。\n", ch);
} else {
printf("'%c' は英字ではありません。\n", ch);
}
return 0;
}
上のプログラムでは、ユーザーから1文字入力してもらい、その文字が英字かどうかをisalphaで判定しています。
if文の条件にそのままisalphaを書き、戻り値が0かどうかで分岐しています。
例えばaを入力した場合の出力例です。
1文字入力してください: a
'a' は英字です。
英字以外を検出する条件分岐の書き方
英字でない文字を検出したい場合、if (!isalpha(...))のように、否定演算子!を使うのが分かりやすいです。
次の例では、英字か英字以外かをメッセージで分けています。
#include <stdio.h>
#include <ctype.h>
int main(void) {
char ch;
printf("1文字入力してください: ");
scanf(" %c", &ch);
// 英字でない文字を検出
if (!isalpha((unsigned char)ch)) {
printf("'%c' は英字ではありません。(数字または記号など)\n", ch);
} else {
printf("'%c' は英字です。\n", ch);
}
return 0;
}
「英字以外」には数字・記号・空白・日本語文字など、あらゆるものが含まれる点に注意してください。
用途に応じて、isdigitやisspaceなど他の関数も組み合わせると、より細かく分類できます。
出力例(入力が3の場合):
1文字入力してください: 3
'3' は英字ではありません。(数字または記号など)
isdigitで数字(0〜9)を判定する方法
isdigitの基本仕様と戻り値
isdigitは、引数の文字が数字(0〜9)かどうかを判定する関数です。
ヘッダctype.hで定義されています。
宣言は概ね次のようになっています。
int isdigit(int c);
仕様はisalphaとよく似ています。
- 引数
cが数字文字(‘0’〜’9’)なら、0以外の値を返します。 - 数字でない場合は、0を返します。
- if文では
if (isdigit((unsigned char)c))のように使います。
「数字」と「数字文字」は別物なので、次の項目で詳しく区別して説明します。
文字と整数の違い
C言語では、数字には2つの意味があります。
1つ目は整数値としての数字です。
例えば1や42のように、計算に使う値です。
型はintやlongなどになります。
2つ目は文字としての数字です。
例えば'1'や'9'のように、あくまで文字として扱われるものです。
型はcharです。
見た目は同じ「1」でも、1と'1'は別物です。
1… 整数リテラル(数値)'1'… 文字リテラル(文字)
isdigitが判定するのは「文字としての数字かどうか」です。
したがって、次のような使い方をします。
char c = '5';
if (isdigit((unsigned char)c)) {
/* '5' は数字文字 */
}
整数値5そのものに対してisdigitを使うことはありません。
if文と組み合わせた数字判定サンプル
ユーザーが入力した1文字が数字かどうかを判定するサンプルです。
#include <stdio.h>
#include <ctype.h>
int main(void) {
char ch;
printf("数字かどうかを判定します。1文字入力してください: ");
scanf(" %c", &ch);
if (isdigit((unsigned char)ch)) {
printf("'%c' は数字(0〜9)です。\n", ch);
} else {
printf("'%c' は数字ではありません。\n", ch);
}
return 0;
}
例えば7を入力した場合の出力例です。
数字かどうかを判定します。1文字入力してください: 7
'7' は数字(0〜9)です。
この段階では、あくまで「1文字が数字かどうか」を判定していることを意識してください。
複数桁の数値(例: “1234”)を数値として扱うには、文字列処理やatoi/strtolなどが必要になります。
数字以外を検出する条件分岐の書き方
数字以外の文字を検出するには、isalphaと同様に否定演算子!を使います。
#include <stdio.h>
#include <ctype.h>
int main(void) {
char ch;
printf("1文字入力してください: ");
scanf(" %c", &ch);
if (!isdigit((unsigned char)ch)) {
printf("'%c' は数字ではありません。\n", ch);
} else {
printf("'%c' は数字(0〜9)です。\n", ch);
}
return 0;
}
例えばAを入力した場合の出力例です。
1文字入力してください: A
'A' は数字ではありません。
「数字以外」には英字・記号・空白などすべて含まれるため、用途によってはisalphaなどと組み合わせて、より詳細な分類を行うとよいです。
アルファベット・数字・それ以外を見分ける実践
文字が英字か数字かを判定するif文の組み方
ここまででisalphaとisdigitの使い方を学びました。
次は、1つの文字について、「英字」「数字」「それ以外」の3種類を判定するif文の組み方を見ていきます。
基本の考え方は次の通りです。
- まず英字かどうかを
isalphaで判定する。 - 英字でなければ、次に数字かどうかを
isdigitで判定する。 - それ以外は「その他の文字」とする。
コードで表すと、次のようになります。
#include <stdio.h>
#include <ctype.h>
int main(void) {
char ch;
printf("1文字入力してください: ");
scanf(" %c", &ch);
if (isalpha((unsigned char)ch)) {
printf("'%c' は英字です。\n", ch);
} else if (isdigit((unsigned char)ch)) {
printf("'%c' は数字です。\n", ch);
} else {
printf("'%c' は英字でも数字でもありません。\n", ch);
}
return 0;
}
if → else if → elseの3段階の分岐にすることで、文字の種類を3つに分類しています。
入力ごとの例:
- 入力
A→ 「英字です」 - 入力
5→ 「数字です」 - 入力
@→ 「英字でも数字でもありません」
elseを使って「それ以外の文字」を判定する
上のサンプルでは、elseの部分が「それ以外の文字」の判定になっています。
ifとelse ifで網羅されなかったすべてのケースが、elseに入ると考えればよいです。
例をもう一度整理すると、次のようになります。
| 条件 | 判定内容 | 該当する文字の例 |
|---|---|---|
isalpha が真 | 英字 | ‘A’, ‘z’ など |
isdigit が真 | 数字 | ‘0’, ‘9’ など |
| 上記以外 | それ以外の文字 | ‘@’, ‘ ‘, ‘あ’ など |
「その他」の中には、日本語・記号・空白・改行など、あらゆる文字が含まれる点を意識しておくと、文字種の全体像をイメージしやすくなります。
isalnumで英数字まとめて判定する方法
ctype.hには、英字か数字のどちらかであれば真を返すisalnumという関数も用意されています。
宣言は次のようになっています。
int isalnum(int c);
仕様は次のようになります。
- 引数
cが英字または数字なら、0以外を返します。 - それ以外の文字の場合は、0を返します。
isalphaとisdigitをまとめたイメージです。
#include <stdio.h>
#include <ctype.h>
int main(void) {
char ch;
printf("1文字入力してください: ");
scanf(" %c", &ch);
if (isalnum((unsigned char)ch)) {
printf("'%c' は英数字(英字または数字)です。\n", ch);
} else {
printf("'%c' は英数字ではありません。\n", ch);
}
return 0;
}
出力例(入力がBの場合):
1文字入力してください: B
'B' は英数字(英字または数字)です。
英字と数字を「同じグループ」として扱いたい場合には、isalnumが非常に便利です。
たとえば「ユーザーIDは英数字のみ許可する」といった入力チェックにそのまま使えます。
複数文字をチェックするループ処理サンプル
ここから少し応用として、文字列の各文字を1つずつ調べるサンプルを紹介します。
C言語では、文字列はcharの配列で表現され、終端に'\0'という終端文字が入っています。
次のプログラムでは、入力された文字列について、各文字が「英字」「数字」「それ以外」のどれに当たるかを表示します。
#include <stdio.h>
#include <ctype.h>
int main(void) {
char str[100]; // 最大99文字 + 終端文字
printf("英字・数字・その他を判定します。文字列を入力してください: ");
// 空白を含む行全体を読み込むにはfgetsを使う
if (fgets(str, sizeof(str), stdin) == NULL) {
printf("入力エラーです。\n");
return 1;
}
printf("各文字の判定結果:\n");
// 文字列の先頭から順に1文字ずつチェック
for (int i = 0; str[i] != '#include <stdio.h>
#include <ctype.h>
int main(void) {
char str[100]; // 最大99文字 + 終端文字
printf("英字・数字・その他を判定します。文字列を入力してください: ");
// 空白を含む行全体を読み込むにはfgetsを使う
if (fgets(str, sizeof(str), stdin) == NULL) {
printf("入力エラーです。\n");
return 1;
}
printf("各文字の判定結果:\n");
// 文字列の先頭から順に1文字ずつチェック
for (int i = 0; str[i] != '\0'; i++) {
char ch = str[i];
// 改行文字はスキップ(不要なら消してもよい)
if (ch == '\n') {
continue;
}
printf("文字 '%c' : ", ch);
if (isalpha((unsigned char)ch)) {
printf("英字\n");
} else if (isdigit((unsigned char)ch)) {
printf("数字\n");
} else {
printf("その他\n");
}
}
return 0;
}
'; i++) {
char ch = str[i];
// 改行文字はスキップ(不要なら消してもよい)
if (ch == '\n') {
continue;
}
printf("文字 '%c' : ", ch);
if (isalpha((unsigned char)ch)) {
printf("英字\n");
} else if (isdigit((unsigned char)ch)) {
printf("数字\n");
} else {
printf("その他\n");
}
}
return 0;
}
例えば、入力がAb3@の場合の出力例です。
英字・数字・その他を判定します。文字列を入力してください: Ab3@
各文字の判定結果:
文字 'A' : 英字
文字 'b' : 英字
文字 '3' : 数字
文字 '@' : その他
このように、for文でstr[i]を順に取り出しながらisalphaやisdigitを使うことで、複数文字の判定が簡単に書けます。
文字チェッカー(対話型プログラム)の作り方
最後に、ユーザーが何度も文字を入力できる、簡単な対話型「文字チェッカー」を作ってみます。
次の仕様にします。
- 1文字ずつ入力して、英字・数字・それ以外を判定して表示する。
#が入力されたら終了する。- エンターキーだけ押された場合なども考慮して、安全に読み込む。
#include <stdio.h>
#include <ctype.h>
int main(void) {
char line[100]; // 入力行全体を受け取るバッファ
char ch;
printf("文字チェッカーを開始します。\n");
printf("# を入力すると終了します。\n\n");
while (1) {
printf("1文字入力してください: ");
// 1行分をfgetsで読み込む
if (fgets(line, sizeof(line), stdin) == NULL) {
printf("入力エラーにより終了します。\n");
break;
}
// 先頭の1文字を取り出す
ch = line[0];
// もし改行だけの行だった場合は、再入力を促す
if (ch == '\n') {
printf("何も入力されませんでした。もう一度入力してください。\n");
continue;
}
// 終了条件
if (ch == '#') {
printf("# が入力されたため、終了します。\n");
break;
}
// 判定
if (isalpha((unsigned char)ch)) {
printf("'%c' は英字です。\n\n", ch);
} else if (isdigit((unsigned char)ch)) {
printf("'%c' は数字です。\n\n", ch);
} else {
printf("'%c' は英字でも数字でもありません。\n\n", ch);
}
}
return 0;
}
このプログラムでは、while文で無限ループを作り、条件を満たしたらbreakで抜けるという構成になっています。
isalphaとisdigitを組み合わせて、「英字」「数字」「それ以外」を対話的に判定できます。
文字チェッカーを開始します。
# を入力すると終了します。
1文字入力してください: A
'A' は英字です。
1文字入力してください: 8
'8' は数字です。
1文字入力してください: @
'@' は英字でも数字でもありません。
1文字入力してください: #
# が入力されたため、終了します。
このような小さなツールを自分で作って試してみると、文字判定関数の動きやif文・ループの感覚がよく身につきます。
まとめ
本記事では、C言語のctype.hを使って、文字がアルファベットか数字か、それ以外かを判定する方法について解説しました。
isalphaで英字、isdigitで数字、isalnumで英数字全体を簡潔に判定できます。
さらに、if文・else if・elseを組み合わせることで、文字を3種類に分類する実用的なプログラムも作成できました。
まずは1文字の判定から練習し、慣れてきたら文字列全体のチェックや入力バリデーションなどにも応用してみてください。
