C言語でcharをintに変換する方法

491, 2022-06-09

目次

C言語でcharをintに変換する方法

C言語にはchar型とint型があります。
この記事ではcharをintに変換する方法、charの配列をintに変換する方法を解説します。
また数字のcharを整数のintに変換する方法も解説します。

この記事を読めばcharをintに変換する方法はばっちりです。

関連記事


charをintにキャストする方法

char型の変数をint型にキャストするには↓のようにします。

#include <stdio.h>

int main(void) {
    char c = 'a';
    int i = c;

    printf("%d\n", i);  // 97

    return 0;
}

↑の場合どこでキャストが発生しているかというとint i = c;の部分です。
C言語では暗黙的なキャスト(型変換)が行われます。
ですのでこのようなコードを書くとキャストが発生します。

明示的にキャストしたい場合は↓のように書きます。

#include <stdio.h>

int main(void) {
    char c = 'a';
    int i = (char) c;

    printf("%d\n", i);  // 97

    return 0;
}

charの数字をintの整数に変換する

char型の数字をint型の整数に変換するには↓のようにします。

#include <stdio.h>

int main(void) {
    char c = '1';
    int i = c - '0';

    printf("%d\n", i);  // 1

    return 0;
}

変換しているのはc - '0'の部分です。
やってるのはただの引き算ですがなぜこれで数字を整数に変換できるのでしょうか?

実はC言語では文字も数値で表現されています。
たとえば数字の'0'は内部では48という整数で表現されています。
つまりcharの文字同士を引き算したり足し算したりすると整数の演算と同じことが起きます。

たとえば↓のコードを見てください。

#include <stdio.h>

int main(void) {
    printf("%c: %d\n", '0', '0');
    printf("%c: %d\n", '1', '1');
    printf("%c: %d\n", '2', '2');
    printf("%c: %d\n", '3', '3');
    printf("%c: %d\n", '4', '4');
    printf("%c: %d\n", '5', '5');
    printf("%c: %d\n", '6', '6');
    printf("%c: %d\n", '7', '7');
    printf("%c: %d\n", '8', '8');
    printf("%c: %d\n", '9', '9');
    return 0;
}

↑は数字とその内部表現である数値を出力しています。
結果は↓になります。

0: 48
1: 49
2: 50
3: 51
4: 52
5: 53
6: 54
7: 55
8: 56
9: 57

↑の結果を見ながらたとえば'0' - '0'を計算してみてください。
そうすると内部表現では48 - 48になるので結果は整数の0です。
そして'1' - '0'も計算してみます。
するとこれは49 - 48になるので結果は整数の1です。

このように数字から数字の'0'を引くと数字の整数としての値が求まります。
この変換ではこのテクニックを使っています。

charの数字をintの整数に変換する関数を作る

さきほどの変換方法を利用してcharの数字をintの整数に変換する関数を作ります。
関数の実装は↓のようになります。

#include <stdio.h>

/**
 * charの数字をintに変換する 
 * 変換できない場合は-1を返す
 * 
 * @param[in] {char} c 数字
 * @return {int} 変換した整数
 */
int chartoint(char c) {
    if (c >= '0' && c <= '9') {
        return c - '0';
    }
    return -1;
}

int main(void) {
    printf("%d\n", chartoint('a'));  // -1
    printf("%d\n", chartoint('0'));  // 0
    printf("%d\n", chartoint('1'));  // 1
    printf("%d\n", chartoint('2'));  // 2
    return 0;
}

↑のchartoint()が数字を整数に変換する関数です。
関数内では最初にif (c >= '0' && c <= '9') {で引数cをチェックしています。
このようなif文を書くとc数字かどうか判定できます。

cが数字で整数に変換できる場合はc - '0'を計算して結果を返します。
cが数字でない場合は-1を返します。

char型の配列をintの整数に変換するatoi関数

ナル終端されたchar型の配列、つまり文字列をintの整数に変換するにはatoi()関数を使います。

#include <stdlib.h>

int atoi(const char *nptr);

この関数に渡すcharの配列はナル終端されてないといけません。
ナル終端とは配列の末尾が\0で終端されていることを言います。
(ポインタ配列の場合は配列の末尾がNULLで終端されている状態です)
このようなcharの配列の末尾が\0で終端されている場合、その配列は文字列と表現します。

atoi()関数は↓のように使います。

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

int main(void) {
    int i = atoi("123");

    printf("%d\n", i);  // 123

    return 0;
}

atoi()関数は文字列を整数に変換できなかった場合は期待した結果とは異なる値を返します。
atoi()関数はエラーを検出できない簡易的な関数です。
そのため神経質な処理には使えません。

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

int main(void) {
    int i = atoi("abc");

    printf("%d\n", i);  // 0

    return 0;
}

char型の配列をlong intに変換するstrtol関数

atoi()関数はエラーを検出できない欠点がありました。
高度なプログラムで整数への変換のエラーを検出したい場合はstrtol()関数を使うのが一般的です。

#include <stdlib.h>

long int strtol(const char *nptr, char **endptr, int base);

この関数は指定した文字列を指定の基数に変換する関数です。
第3引数の基数とはつまり10進数にしたい場合は10を、16進数にしたい場合は16を指定します。

第1引数には変換対象の文字列を渡します。

第2引数には変換不可能な文字列へのポインタの保存先を指定します。
これは通常はNULLを指定します。

strtol()は変換に失敗した場合はerrnoにエラーをセットします。
引数のbaseがサポートしていない値だった場合はEINVALを。
値が範囲外であればERANGEを返します。

↓のように使います。

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

int main(void) {
    long int i = strtol("123", NULL, 10);  // 10進数に変換
    printf("%ld\n", i);  // 123

    char *endptr = NULL;
    strtol("123abc", &endptr, 10);
    if (strlen(endptr)) {
        printf("変換できない文字列が含まれています: %s\n", endptr);
        // 変換できない文字列が含まれています: abc
    }

    errno = 0;
    strtol("123", NULL, 12345);
    if (errno == EINVAL) {
        perror("strtol");  // strtol: Invalid argument
    }

    errno = 0;
    strtol("123456789123456789123456789", NULL, 10);
    if (errno == ERANGE) {
        perror("strtol");  // strtol: Numerical result out of range
    }

    return 0;
}

endptrのポインタを参照し、その長さが0でなければ文字列には変換できない文字列が含まれています。
123abcendptrabcになり、abc123endptrabc123になります。
abcの場合もendptrabcになります。
123の場合はendptrは空文字列になります。

errnoは関数の呼び出し前に0クリアしておくのが大事です。
こうすると誤検出を減らせます。

perror()は内部でerrnoを参照してそのエラー内容を文字列で出力してくれます。
Invalid argument」は「不正な引数」という意味です。
Numerical result out of range」は「結果が範囲外です」という意味になります。

おわりに

今回はC言語のchar型をint型に変換する方法を解説しました。
文字を整数に変換したいケースはけっこうよくありますよね。
この記事が参考になれば幸いです。

(^ _ ^)

C言語の文字は数値で表現されている

(・ v ・)

それを利用すれば変換できる



この記事のアンケートを送信する