閉じる

【C言語】英字・数字を判定する方法(isalpha/isdigit)

英字や数字の判定は、入力チェックやトークナイズ、フォーマット検証など多くの場面で必要になります。

本記事では<ctype.h>に用意されているisalphaisdigitの使い方を、初心者の方にもわかりやすいよう丁寧に解説します。

判定の基本、注意点、実用パターンまで順を追って説明します。

C言語での英字・数字判定

C言語では、文字が英字か数字かといった分類を行う関数群が<ctype.h>に用意されています。

代表的なものがisalpha(英字判定)とisdigit(数字判定)です。

これらの関数は引数にintを受け取り、真(非0)または偽(0)を返します。

使う前に#include <ctype.h>を忘れないようにします。

もっとも重要な注意点は、これらの関数に渡す値はunsigned charに変換可能なintEOFでなければならないということです

多くの環境でcharは符号付きになり得るため、必ず(unsigned char)cにキャストしてから渡すのが安全です。

これを怠ると未定義動作になる可能性があります。

また、isalphaなど一部の判定はロケールに依存します。

一方でisdigitはロケール非依存で、常にASCIIの'0''9'だけを数字とみなします。

UTF-8の全角数字(例: )はisdigitでは数字と判定されません。

次の表に概要をまとめます。

関数名判定対象真(非0)になる例偽(0)になる例備考(注意)
isalpha英字'A', 'z''@', '7'ロケール依存。入力は(unsigned char)にキャスト
isdigit数字'0''9''A', 全角数字'1'ロケール非依存。ASCIIの数字のみ

ポイントとして、これらの関数はboolではなくintを返しますが、条件式では非0が真として扱われるため、if (isalpha(...))のようにそのまま使います。

比較して== 1のように書く必要はありません。

isalphaの使い方とコード例

英字かを判定する例

isalphaは、引数の文字が英字(アルファベット)なら非0を返します。

大文字・小文字の区別なく判定されます。

C言語
#include <stdio.h>
#include <ctype.h>

// 文字が英字かを調べて表示するデモ
int main(void) {
    const char s[] = "Az7#";
    for (size_t i = 0; s[i] != '
#include <stdio.h>
#include <ctype.h>
// 文字が英字かを調べて表示するデモ
int main(void) {
const char s[] = "Az7#";
for (size_t i = 0; s[i] != '\0'; ++i) {
unsigned char uc = (unsigned char)s[i]; // 安全のためにunsigned charへ
if (isalpha(uc)) {
printf("%c は英字です\n", s[i]);
} else {
printf("%c は英字ではありません\n", s[i]);
}
}
return 0;
}
'; ++i) { unsigned char uc = (unsigned char)s[i]; // 安全のためにunsigned charへ if (isalpha(uc)) { printf("%c は英字です\n", s[i]); } else { printf("%c は英字ではありません\n", s[i]); } } return 0; }
実行結果
A は英字です
z は英字です
7 は英字ではありません
# は英字ではありません

常に(unsigned char)にキャストしてから渡すのが安全です。

特に拡張ASCII(0x80以上)のバイト値を扱う可能性がある場合は必須です。

大文字と小文字の扱い

isalphaは大文字と小文字を区別しないで英字と判定します。

C言語
#include <stdio.h>
#include <ctype.h>

int main(void) {
    const char s[] = "AaZz";
    for (size_t i = 0; s[i] != '
#include <stdio.h>
#include <ctype.h>
int main(void) {
const char s[] = "AaZz";
for (size_t i = 0; s[i] != '\0'; ++i) {
unsigned char uc = (unsigned char)s[i];
printf("%c -> isalpha: %s\n", s[i], isalpha(uc) ? "true" : "false");
}
return 0;
}
'; ++i) { unsigned char uc = (unsigned char)s[i]; printf("%c -> isalpha: %s\n", s[i], isalpha(uc) ? "true" : "false"); } return 0; }
実行結果
A -> isalpha: true
a -> isalpha: true
Z -> isalpha: true
z -> isalpha: true
補足

大文字・小文字の変換はtoupper/tolowerで行えますが、本記事では判定に焦点を当てます。

英字でない場合の判定

英字以外を弾きたい場合は、否定演算子!を使います。

数字や記号は「英字ではない」と判定されます。

C言語
#include <stdio.h>
#include <ctype.h>

int main(void) {
    const char s[] = "123!?_";
    for (size_t i = 0; s[i] != '
#include <stdio.h>
#include <ctype.h>
int main(void) {
const char s[] = "123!?_";
for (size_t i = 0; s[i] != '\0'; ++i) {
unsigned char uc = (unsigned char)s[i];
if (!isalpha(uc)) {
printf("%c は英字ではありません\n", s[i]);
}
}
return 0;
}
'; ++i) { unsigned char uc = (unsigned char)s[i]; if (!isalpha(uc)) { printf("%c は英字ではありません\n", s[i]); } } return 0; }
実行結果
1 は英字ではありません
2 は英字ではありません
3 は英字ではありません
! は英字ではありません
? は英字ではありません
_ は英字ではありません

UTF-8の日本語文字のような多バイト文字の各バイトに対してisalphaを呼んでも、正しい“文字”判定にはなりません

多言語の全文字を扱うなら<wctype.h>iswalphaなどワイド文字APIを検討します。

isdigitの使い方とコード例

数字かを判定する例

isdigitはASCIIの'0''9'のみを数字として扱います。

C言語
#include <stdio.h>
#include <ctype.h>

int main(void) {
    const char s[] = "5x09";
    for (size_t i = 0; s[i] != '
#include <stdio.h>
#include <ctype.h>
int main(void) {
const char s[] = "5x09";
for (size_t i = 0; s[i] != '\0'; ++i) {
unsigned char uc = (unsigned char)s[i];
if (isdigit(uc)) {
printf("%c は数字です\n", s[i]);
} else {
printf("%c は数字ではありません\n", s[i]);
}
}
return 0;
}
'; ++i) { unsigned char uc = (unsigned char)s[i]; if (isdigit(uc)) { printf("%c は数字です\n", s[i]); } else { printf("%c は数字ではありません\n", s[i]); } } return 0; }
実行結果
5 は数字です
x は数字ではありません
0 は数字です
9 は数字です

全角のやローマ数字などはisdigitでは数字と判定されません

‘0’〜’9’の範囲を確認

isdigit(c)'0' <= c && c <= '9'は、ASCII環境では同じ結果になります。

以下で比較します。

C言語
#include <stdio.h>
#include <ctype.h>

int main(void) {
    const char s[] = "5A"; // '5' と 'A' を比較
    for (size_t i = 0; s[i] != '
#include <stdio.h>
#include <ctype.h>
int main(void) {
const char s[] = "5A"; // '5' と 'A' を比較
for (size_t i = 0; s[i] != '\0'; ++i) {
unsigned char uc = (unsigned char)s[i];
int a = isdigit(uc);                 // ctype関数による判定
int b = ('0' <= s[i] && s[i] <= '9'); // 文字の範囲による判定
printf("%c -> isdigit:%d, 範囲チェック:%d\n", s[i], a, b);
}
return 0;
}
'; ++i) { unsigned char uc = (unsigned char)s[i]; int a = isdigit(uc); // ctype関数による判定 int b = ('0' <= s[i] && s[i] <= '9'); // 文字の範囲による判定 printf("%c -> isdigit:%d, 範囲チェック:%d\n", s[i], a, b); } return 0; }
実行結果
5 -> isdigit:1, 範囲チェック:1
A -> isdigit:0, 範囲チェック:0

実務ではisdigitを使うのが簡潔で読みやすいです。

範囲チェックは外部仕様で文字集合が明確なときに限って選択するとよいです。

文字列中の数字を数える

文字列に含まれる数字の個数を数える例です。

C言語
#include <stdio.h>
#include <ctype.h>

// 文字列中の数字の個数を数える
int main(void) {
    const char *s = "Tel:+81-90-1234-5678";
    int count = 0;
    for (size_t i = 0; s[i] != '
#include <stdio.h>
#include <ctype.h>
// 文字列中の数字の個数を数える
int main(void) {
const char *s = "Tel:+81-90-1234-5678";
int count = 0;
for (size_t i = 0; s[i] != '\0'; ++i) {
if (isdigit((unsigned char)s[i])) {
++count;
}
}
printf("数字の個数: %d\n", count);
return 0;
}
'; ++i) { if (isdigit((unsigned char)s[i])) { ++count; } } printf("数字の個数: %d\n", count); return 0; }
実行結果
数字の個数: 12

電話番号やIDの抽出などでよく使うパターンです。

実用パターンと関連関数

文字列を走査して英字/数字を数える

英字と数字を同時に数えると、簡易的なバリデーションができます。

C言語
#include <stdio.h>
#include <ctype.h>

// 英字と数字の個数を同時に集計する
int main(void) {
    const char *s = "Hello C99 world! 2025";
    int alpha_count = 0;
    int digit_count = 0;

    for (size_t i = 0; s[i] != '
#include <stdio.h>
#include <ctype.h>
// 英字と数字の個数を同時に集計する
int main(void) {
const char *s = "Hello C99 world! 2025";
int alpha_count = 0;
int digit_count = 0;
for (size_t i = 0; s[i] != '\0'; ++i) {
unsigned char uc = (unsigned char)s[i];
if (isalpha(uc)) {
++alpha_count;
} else if (isdigit(uc)) {
++digit_count;
}
// それ以外(空白・記号など)は今回は無視
}
printf("英字の個数: %d\n", alpha_count);
printf("数字の個数: %d\n", digit_count);
return 0;
}
'; ++i) { unsigned char uc = (unsigned char)s[i]; if (isalpha(uc)) { ++alpha_count; } else if (isdigit(uc)) { ++digit_count; } // それ以外(空白・記号など)は今回は無視 } printf("英字の個数: %d\n", alpha_count); printf("数字の個数: %d\n", digit_count); return 0; }
実行結果
英字の個数: 11
数字の個数: 6

クラス判定は「合致したら次へは行かない」ようにif/else ifで順序付けすると読みやすくなります

英数字の一括判定

英字または数字であるかを一度に判定したい場合は、isalnumが便利です。

これはisalphaisdigitの論理和に相当します。

C言語
#include <stdio.h>
#include <ctype.h>

// 英数字だけを抽出して新しい文字列を作る
int main(void) {
    const char *src = "ID: X9-007_A";
    char dst[64] = {0};
    size_t j = 0;

    for (size_t i = 0; src[i] != '
#include <stdio.h>
#include <ctype.h>
// 英数字だけを抽出して新しい文字列を作る
int main(void) {
const char *src = "ID: X9-007_A";
char dst[64] = {0};
size_t j = 0;
for (size_t i = 0; src[i] != '\0'; ++i) {
unsigned char uc = (unsigned char)src[i];
if (isalnum(uc)) {             // 英数字ならコピー
dst[j++] = (char)uc;
}
// 記号や空白はスキップ
}
printf("元文字列: %s\n", src);
printf("英数字のみ: %s\n", dst);
return 0;
}
'; ++i) { unsigned char uc = (unsigned char)src[i]; if (isalnum(uc)) { // 英数字ならコピー dst[j++] = (char)uc; } // 記号や空白はスキップ } printf("元文字列: %s\n", src); printf("英数字のみ: %s\n", dst); return 0; }
実行結果
元文字列: ID: X9-007_A
英数字のみ: IDX9007A

ユーザーIDやファイル名の正規化などでよく使います。

アンダースコアはisalnumでは英数字に含まれない点に注意してください。

条件分岐の書き方

判定関数は非0/0を返すため、比較は不要です。

組み合わせる場合は論理演算子を使います。

C言語
#include <stdio.h>
#include <ctype.h>

// 文字を分類して表示する
int main(void) {
    const char *s = "A1 _!";
    for (size_t i = 0; s[i] != '
#include <stdio.h>
#include <ctype.h>
// 文字を分類して表示する
int main(void) {
const char *s = "A1 _!";
for (size_t i = 0; s[i] != '\0'; ++i) {
unsigned char uc = (unsigned char)s[i];
if (isalpha(uc)) {
printf("%c -> 英字\n", s[i]);
} else if (isdigit(uc)) {
printf("%c -> 数字\n", s[i]);
} else if (isspace(uc)) { // 関連関数: 空白類判定
printf("(space) -> 空白\n");
} else {
printf("%c -> その他\n", s[i]);
}
}
return 0;
}
'; ++i) { unsigned char uc = (unsigned char)s[i]; if (isalpha(uc)) { printf("%c -> 英字\n", s[i]); } else if (isdigit(uc)) { printf("%c -> 数字\n", s[i]); } else if (isspace(uc)) { // 関連関数: 空白類判定 printf("(space) -> 空白\n"); } else { printf("%c -> その他\n", s[i]); } } return 0; }
実行結果
A -> 英字
1 -> 数字
(space) -> 空白
_ -> その他
! -> その他

書き方のコツとして、以下を押さえると安全で読みやすくなります。

(1) 引数は(unsigned char)にキャストする、(2) 比較== 1は不要、(3) 条件の優先順位を意図どおりに並べる

まとめ

本記事では<ctype.h>isalphaisdigitを中心に、英字・数字の判定方法と実用例を解説しました。

最重要ポイントは、引数を(unsigned char)にキャストして未定義動作を避けること、そしてisdigitはASCIIの'0''9'のみを数字とするという仕様です。

英数字をまとめて判定するisalnumや、空白判定isspaceなど関連関数と組み合わせることで、入力検証やトークナイズ処理がシンプルに記述できます。

多言語の文字を扱う必要がある場合は<wctype.h>のワイド文字版関数も検討すると良いでしょう。

用途に応じて適切な関数を選び、堅牢な文字処理を実現してください。

この記事を書いた人
エーテリア編集部
エーテリア編集部

プログラミングの基礎をしっかり学びたい方向けに、C言語の基本文法から解説しています。ポインタやメモリ管理も少しずつ理解できるよう工夫しています。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!