第7章の2 文字操作関数

1. 代表的な文字操作関数

文字検査や文字変換を行う関数です。
大文字、小文字などの文字検査や大文字から小文字への文字変換などを行います。
#include <ctype.h> が必要です。「#include」については「18-2」 を参照してください。

なお、変数は全て int型であり、unsigned char で表現可能、または EOF でなければなりません。

【文字操作関数】
関数 説明 使用例
isalnum(c) 文字c が英数字(A~Z、a~z、0~9)なら真(0以外の数)を返す。
文字c が英数字以外なら偽(0)を返す。
int c;

c = getchar();
if (isalnum(c) != 0) {
	printf("英数字入力\n");
}
isalpha(c) 文字c が英文字(A~Z、a~z)なら真(0以外の数)を返す。
文字c が英文字以外なら偽(0)を返す。
int c;

c = getchar();
if (isalpha(c) != 0) {
	printf("英文字入力\n");
}
isdigit(c) 文字c が数字(0~9)なら真(0以外の数)を返す。
文字c が数字以外なら偽(0)を返す。
int c;

c = getchar();
if (isdigit(c) != 0) {
	printf("数字入力\n");
}
islower(c) 文字c が英小文字(a~z)なら真(0以外の数)を返す。
文字c が英小文字以外なら偽(0)を返す。
int c;

c = getchar();
if (islower(c) != 0) {
	printf("英小文字入力\n");
}
isupper(c) 文字c が英大文字(A~Z)なら真(0以外の数)を返す。
文字c が英大文字以外なら偽(0)を返す。
int c;

c = getchar();
if (isupper(c) != 0) {
	printf("英大文字入力\n");
}
isxdigit(c) 文字c が16進表示文字(0~9、A~F、a~f)なら真、それ以外なら偽を返す。
int c;

c = getchar();
if (isxdigit(c) != 0) {
	printf("16進表示文字\n");
}
iscntrl(c) 文字c が制御文字(0x00~0x1f、0x7f)なら真、それ以外なら偽を返す。
isprint(c) 文字c が印字可能文字(0x20~0x7e)なら真、それ以外なら偽を返す。
isgraph(c) 文字c が空白を除く印字可能文字(0x21~0x7e)なら真、それ以外なら偽を返す。
ispunct(c) 文字c が区切り文字(0x21~0x2f、0x3a~0x40、0x5b~0x60、0x7b~0x7e)なら真、それ以外なら偽を返す。
isspace(c) 文字c が空白、タブ、復帰、改行、垂直タブ、改頁(0x09~0x0d、0x20)なら真、それ以外なら偽を返す。
tolower(c) 文字c が大文字なら、小文字に変換した値を返す。
大文字以外なら、そのままの値を返す。
int c, ch;

c = getchar();
ch = tolower(c);
printf("小文字変換 = %c\n", ch);
toupper(c) 文字c が小文字なら、大文字に変換した値を返す。
小文字以外なら、そのままの値を返す。
int c, ch;
c = getchar();
ch = toupper(c);
printf("大文字変換 = %c\n", ch);

使用例で用いている getchar()関数は、1文字をint型で入力する関数です。
第8章で扱います。

〇 演習問題

問1

ASCIIコード(0~127)のうち印字可能(空白含む)な文字を表示しなさい。なお、その際、英数字以外の文字は [ ] で囲みなさい。

【実行結果例】
[ ][!][“][#][$][%][&][‘][(][)][*][+][,][-][.][/]0123456789[:][;][<][=][>][?][@]A
BCDEFGHIJKLMNOPQRSTUVWXYZ[[][\][]][^][_][`]abcdefghijklmnopqrstuvwxyz[{][|][}][~]

問2

文字型配列 str に “AbcDefGHijk1234lmNOP” という文字列が格納されている。文字操作のライブラリ関数を用いて、この文字列の小文字を全て大文字に変換しなさい。

【実行結果例】
str = ABCDEFGHIJK1234LMNOP

問3

16進数に変換可能な文字列(例えば “AB45″)をキーボードから入力し、10進数の数値に変換しなさい。ただし、文字コードはASCIIとします。

【実行結果例】
16進数を入力 > AB45
10進数:43845

水色文字はキーボードからの入力

解答例

// 問1
#include <stdio.h>
#include <ctype.h>

int main(void)
{
    int ch;

    for (ch = 0; ch <= 127; ch++) {
        if (isprint(ch) != 0) {
            if (isalnum(ch) != 0) {
                printf("%c", ch);
            }
            else {
                printf("[%c]", ch);
            }
        }
    }

    return 0;
}
// 問2
#include <stdio.h>
#include <ctype.h>

int main(void)
{
    char str[] = "AbcDefGHijk1234lmNOP";
    int i;

    i = 0;
    while (str[i] != '\0') {
        str[i] = toupper(str[i]);
        i++;
    }
    printf("str = %s\n", str);

    return 0;
}
// 問3
#include <stdio.h>
#include <ctype.h>

int main(void)
{
    char str[100];
    int x = 0;
    int i = 0;

    printf("16進数を入力 > ");
    scanf("%99s", str);

    // データ変換処理
    while (str[i] != '\0') {
        // 16進数で表せる文字か
        if (isxdigit(str[i]) != 0) {
            // 数字で表せる文字か
            if(isdigit(str[i]) != 0) {
                // 10進数に変換
                x = x * 16 + str[i] - '0';
            }
            else {
                // 大文字は小文字にしておく
                str[i] = tolower(str[i]);
                // 10進数に変換
                x = x * 16 + str[i] - 'a' + 10;
            }
        }
        else {
            printf("変換エラー:16進数として解釈できません。\n");
            return 0;
        }
        i++;
    }
    printf("10進数:%d\n", x);
    
    return 0;
}

この問題は、strtolを用いると次のように書き替えが可能です。

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char str[100];
    char *endptr;
    long x;

    printf("16進数を入力 > ");
    scanf("%99s", str);

    // 基数16で変換
    x = strtol(str, &endptr, 16);

    // 変換できなかった場合や、不正な文字が含まれていた場合
    if (*endptr != '\0') {
        printf("変換エラー:16進数として解釈できません。\n");
    } else {
        printf("10進数:%ld\n", x);
    }

    return 0;
}

また、sscanfを用いると次のようになります。

#include <stdio.h>

int main(void)
{
    char str[100];
    int x;

    printf("16進数を入力 > ");
    scanf("%99s", str);

    // 文字列から16進数として整数を読み取る
    if (sscanf(str, "%x", &x) == 1) {
        printf("10進数:%d\n", x);
    } else {
        printf("変換エラー:16進数として解釈できません。\n");
    }

    return 0;
}

コメント