【C言語】文字の種類を判別する関数(isalnum・isspace・isprintなど)

文字の種類を判別する関数の紹介ページアイキャッチ

このページでは、文字の種類を判別する下記の標準ライブラリ関数の紹介をしていきます。

  • isalnum
  • isalpha
  • islower
  • isupper
  • isdigit
  • isxdigit
  • isprint
  • isgraph
  • ispunct
  • isspace
  • isblank
  • iscntrl
  • isascii

関数の数は多いですが、各関数で共通している部分が多いため、1つの関数が使えれば他の関数も簡単に使いこなすことができます。

このページでは、まず各関数で共通となる使い方について説明し、次に各関数固有の「判別可能な文字の種類」ついて解説します。

最後に、いくつかの関数をピックアップして具体的な使用例を紹介していきます。

各関数の共通の使い方

まずは、各関数で共通となる使い方について解説していきます。

ページの最初に紹介した13個の関数は全て、ctype.h をインクルードしてから使用します。

さらに全ての関数において、返却値の型や引数の型・引数の個数は同じになります。

例えば isalnum 関数は下記のように宣言されており、他の関数も同じく返却値の型は int、引数は int 型の c のみとなります。

isalnum

#include <ctype.h>

int isalnum(int c);

ここからは、ページの最初に紹介した13個の関数をまとめて isxxxxx 関数と呼ばせていただきます。

isxxxxx 関数は、引数 c の文字が「特定の種類の文字」であるかどうかを判定し、「特定の種類の文字」である場合には 0 “以外” を返却し、「特定の種類の文字」でない場合は 0 を返却します。

「特定の種類の文字」は関数によって異なります。詳細は後述の 各関数が判別可能な文字の種類 で解説しますが、例えば isdigit 関数では「特定の種類の文字」は「数字」となりますので、引数 c の文字が 09 のいずれかの場合に 0 以外を返却し、それ以外の場合は 0 を返却します。

また、isalpha 関数では「特定の種類の文字」は「アルファベット」となります。

こんな感じで、各関数で判定する「特定の種類の文字」は異なるものの、isxxxxx 関数の返却値や引数は共通しているため、全て下記の形式の処理によって文字の判別を行うことができることになります。

isxxxxxの使い方

if (isxxxxx(c)) {
    特定の種類の文字である場合の処理;
} else {
    特定の種類の文字である場合の処理;
}

例えば、c が10進数の数字である場合のみ printf で出力し、それ以外の場合はスペースを表示するようにしたいのであれば、下記のように処理を記述することになります。

isalphaの使用例

if (isdigit(c)) {
    printf("%c", c);
} else {
    printf(" ");
}

こんな感じで、isxxxxx 関数を利用すれば、引数で指定された文字を判別し、判別結果に応じて処理を切り替えるようなことが可能になります。

各関数が判別可能な文字の種類

前述の通り、ページの最初に挙げた各関数は「特定の種類の文字」かどうかを判定する関数であり、この判定結果により文字の種類を判別することが可能です。

この「特定の種類の文字」は関数によって異なりますので、次は各関数における「特定の種類の文字」について、すなわち各関数が判別可能な文字の種類について解説していきます。

文字は全て半角であることを前提とした解説になっていますのでご注意ください。

スポンサーリンク

isalnum

isalnum 関数は、引数 c の文字が「数字 or アルファベット」であるかどうかを判定する関数です。

isalnum 関数が 0 以外の値を返却する文字には下記のようなものが存在します。

  • 09
  • az
  • AZ

isalpha

isalpha 関数は、引数 c の文字が「アルファベット」であるかどうかを判定する関数です。

isalpha 関数が 0 以外の値を返却する文字には下記のようなものが存在します。

  • az
  • AZ

islower

islower 関数は、引数 c の文字が「小文字のアルファベット」であるかどうかを判定する関数です。

islower 関数が 0 以外の値を返却する文字には下記のようなものが存在します。

  • az

スポンサーリンク

isupper

isupper 関数は、引数 c の文字が「大文字のアルファベット」であるかどうかを判定する関数です。

isupper 関数が 0 以外の値を返却する文字には下記のようなものが存在します。

  • AZ

isdigit

isdigit 関数は、引数 c の文字が「数字」であるかどうかを判定する関数です。

isdigit 関数が 0 以外の値を返却する文字には下記のようなものが存在します。

  • 09

isxdigit

isxdigit 関数は、引数 c の文字が「16進数を表すために利用される文字」であるかどうかを判定する関数です。

isxdigit 関数が 0 以外の値を返却する文字には下記のようなものが存在します。

  • 09
  • a 〜 f
  • AF

スポンサーリンク

isprint

isprint 関数は、引数 c の文字が「印字可能な文字 or スペース」であるかどうかを判定する関数です。

印字可能な文字とは、簡単に言えば “文字として出力される” 文字になります。

文字には “制御を行うことを目的に用意された文字” があり、文字として出力されない文字があります。例えば改行文字などは制御を行うことを目的に用意された文字であって、改行はされるものの文字自体は出力されないですよね。

isprint 関数は、こういった制御を行うことを目的とした文字ではなく、文字として出力される文字であるかどうかを判定する関数になります。ただし、スペースに関しては 0 以外が返却されます。

isprint 関数が 0 以外の値を返却する文字には下記のようなものが存在します。

  • スペース
  • 09
  • a 〜 f
  • AF
  • !#$ などの記号

isgraph

isgraph 関数は、引数 c の文字が「印字可能な文字」であるかどうかを判定する関数です。

isprint 関数と似ていますが、isgraph 関数ではスペースに関しては 0 が返却されます。

isgraph 関数が 0 以外の値を返却する文字には下記のようなものが存在します。

  • 09
  • a 〜 f
  • AF
  • !#$ などの記号

ispunct

ispunct 関数は、引数 c の文字が「数字とアルファベットを除く印字可能な文字」であるかどうかを判定する関数です。

ispunct 関数が 0 以外の値を返却する文字には下記のようなものが存在します。

  • !#$ などの記号

スポンサーリンク

isspace

isspace 関数は、引数 c の文字が「空白文字」であるかどうかを判定する関数です。

制御文字の中でも何かしらの空白が出力される文字の場合に 0 以外が返却される感じだと思います。

isspace 関数が 0 以外の値を返却する文字には下記のようなものが存在します。

  • スペース
  • 水平タブ
  • 垂直タブ
  • 改行 など

isblank

isblank 関数は、引数 c の文字が「スペース or 水平タブ」であるかどうかを判定する関数です。

isblank 関数が 0 以外の値を返却する文字には下記のようなものが存在します。

  • スペース
  • 水平タブ

iscntrl

iscntrl 関数は、引数 c の文字が「制御文字」であるかどうかを判定する関数です。

“文字として出力される” 文字ではなく、”制御を行う” 文字の場合に 0 以外が返却されます。

C言語でよく利用するヌル文字の場合も 0 以外が返却されます。

iscntrl 関数が 0 以外の値を返却する文字には下記のようなものが存在します。

  • ヌル文字
  • 改行
  • 復帰
  • タブ など

スポンサーリンク

isascii

isascii 関数は、引数 c の文字が「ASCII 文字」であるかどうかを判定する関数です。

一言でいえば、文字コードが 0127 の文字の場合に 0 以外が返却されます。ここまで紹介した全ての文字に対して 0 以外が返却されます。

関数の利用例

最後に、ここまで紹介してきた関数のいくつかを用いて利用例を示していきたいと思います。

小文字アルファベットのみ大文字にする

一番関数の意味合いや使い所がわかりやすいのは islower 関数や isupper 関数だと思います。

これらを利用して、小文字アルファベットの場合のみ or 大文字アルファベットの場合のみ特定の処理を行うようなことが可能になります。

例えば、下記は islower 関数を利用し、小文字アルファベットを大文字に変換して出力する例となります。

islower関数の利用例

#include <stdio.h>
#include <ctype.h>
#include <string.h>

int main(void) {
    char str[256] = "Hello World!";
    unsigned int len = strlen(str);

    printf("before : %s\n", str);

    for (unsigned int i = 0; i < len; i++) {
        if (islower(str[i])) {
            str[i] = toupper(str[i]);
        }
    }

    printf("after : %s\n", str);
}

実行結果は下記のようになります。元々小文字であった文字のみが大文字に変化して出力されていること、さらに他の文字はそのまま出力されている(つまり toupper 関数が実行されていない)ことが確認できると思います。

before : Hello World!
after : HELLO WORLD!

ここまでの説明でも明らかなように、isxxxxx 関数で判定可能なのは1文字のみです。

ですので、上記のソースコードの例のように、文字列の場合は1文字ずつ isxxxxx 関数で判定を行なって判別していく必要があります。

また、上記のソースコードでは大文字への変換を toupper 関数を利用して実現しています。toupper 関数については下記ページでも解説していますので、詳しく知りたい方は下記ページをご参照いただければと思います。

C言語での大文字 ⇔ 小文字変換の方法を解説

スポンサーリンク

印字可能な文字のみ出力する

個人的に覚えておくと便利だと思うのが isprint 関数や isgraph 関数です。

印字可能でない文字を出力してしまうと、変に空白が表示されたり改行が入ってしまったりして見た目が悪くなるような時があります。

こんな時に isprint 関数を利用すれば、印字可能でない文字の出力を行わないような制御を実現することができるようになります。

例えば、下記ページで紹介しているようなバイナリデータを文字として出力するような場合に利用したりします。

【C言語】hexdump(16進ダンプ)を自作する

下記は、isprint 関数で印字可能な文字のみをそのまま出力し、それ以外の文字は . で出力する例となります。

isprint関数の利用例

#include <stdio.h>
#include <ctype.h>

int main(void) {

    printf("before :");
    for (int i = 0; i < 128; i++) {
        printf("%c", i);
    }
    printf("\n");
    printf("\n");

    printf("after :");
    for (int i = 0; i < 128; i++) {
        if (isprint(i)) {
            printf("%c", i);
        } else {
            printf(".");
        }
    }
    printf("\n");
}

実行結果は下記のようになります。

before :


123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

after :................................ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~.

上記のソースコードでは、前半部分では文字コードが 0127 の文字をそのまま出力しています。そのため、実行結果からわかるように変に改行が入ってしまったりしています。

その一方で、後半部分では isprint0 を返却する場合は . を出力するようにしているため、印字可能でない文字の出力を防ぎ、改行などが入らないようにすることに成功しています(ブラウザの表示の都合でもしかしたら変に改行が入ってしまっているかも…)。

空白文字を1つにまとめて処理する

あとは私が使った覚えがあるのは isspace 関数くらいですかね。

isspace 関数は、単に空白文字の出力をスキップするような場合にも活躍しますし、空白文字の数や種類に関係なく同じ処理を行いたいような場面でも活躍します。

C言語のソースコードも、スペースやタブ等の数に関わらず同じように命令が解釈される場合がありますよね。

例えば下記は全て、空白文字の数や種類に関わらず同じ命令と解釈されます。

空白文字の数に関係なく同じ命令となる

int x = 100;
int x	=	100;
int       x      =100;
int x =
    100;

こんな感じで、空白文字の数や種類に関わらず同じような結果が得られるようなプログラムを実現したい場合に isspace 関数が活躍します。

下記は、isspace 関数を利用し、連続して現れる空白文字をまとめて1つのスペースのみで出力する例となります。

isspace関数の利用例

#include <stdio.h>
#include <ctype.h>
#include <string.h>

int main(void) {

    char str[] = "x \t     =\t\n     0";

    printf("before : %s\n", str);

    printf("after : ");

    int num_space = 0;
    for (int i = 0; i < strlen(str); i++) {
        if (isspace(str[i])) {
            if (num_space == 0) {
                printf(" ");
            }
            num_space++;
        } else {
            printf("%c", str[i]);
            num_space = 0;
        }
    }
    printf("\n");
}

実行結果は下記のようになります。before の結果ではそのまま空白文字(スペースやタブや改行)が出力されていますが、after の結果では、strの中の連続して現れる空白文字が1つのスペースとして表示されるようになっています。

before : x           =
     0
after : x = 0

num_space で空白文字が連続して現れた文字数をカウントしており、このカウント結果と isspace 関数の返却値をうまく利用して、連続して現れる空白文字をまとめて1つのスペースで出力する動作を実現しています。

まとめ

このページでは、C言語の文字の種類を判別する関数である isalnumisspaceisprint 関数等の紹介を行いました!

文字を扱うプログラムを作成する際には文字の種類を判別したくなる場面は結構多いです。ですので、こういった文字の種類の判別を行う標準関数の存在は覚えておくと良いと思います。

また、これらの関数を利用する際には ctype.h をインクルードする必要があります。普段あまり使わないヘッダーファイルだと思いますので、ctype.h というヘッダーファイルが存在することも是非覚えておいてください!

同じカテゴリのページ一覧を表示