C言語 atoi関数【文字列の数字を数値へ変換する簡単な方法】

C言語
この記事は約9分で読めます。

こんにちは、ナナです。

C言語のプログラムの中で「文字で表現された数字を、数値に変えたい!」と、思うことってあるんです。例えば、数字 “123” を数値「123」に変換したい、そんなシーンですね。

なぜ、こんなことがしたいかというと、数字 “123” は文字であるがゆえに計算ができないんです。計算するためには数値「123」にする必要があります。

数字と数値の違い

注意:この記事においては意識的に、文字で表現された数のことを「数字」、計算可能な数のことを「数値」と表現を切り分けて解説します。

本記事では次の悩みを解消する内容となっています。

本記事の悩み解決リスト
  • atoi関数系の標準ライブラリ関数一覧とは?
  • atoi関数を使った簡単なサンプルコードとは?
  • atoi関数へ様々な文字列を入力したときの出力結果とは?
  • atof関数へ様々な文字列を入力したときの出力結果とは?
  • atoi関数とsscanf関数の使い分けとは?

では、「数字」から「数値」への変換方法を学んでいきましょう。

※atoi関数を使うと簡単な数字なら数値に変換ができますが、複雑な変換を求めているのであればsscanf関数の利用をオススメします。

スポンサーリンク

文字列の数字を数値へと変換するための標準ライブラリ関数

C言語で「数字」を「数値」へ変換するための標準ライブラリ関数は、次の関数になります。

変換ライブラリ関数一覧

#include <stdlib.h>

int atoi(const char * string);      //  ascii to integer
long atol(const char * string);     //  ascii to long
double atof(const char * string);   //  ascii to float(double)

よく見ると、引数は同じデータ型ですが、戻り値の型が異なっていますね。C言語は型制約の強い言語のため、データ型の種類に応じて関数を定義しています。

atoiとは「ascii(アスキーコードの文字) to(を) integer(整数型へ)」という意味になります。このような名前の法則を知っておくと、記憶に残りやすくなります。

ナナ
ナナ

注意としてはatof関数は「float型」の略ですが、戻り値の型は「double型」になっていることですね。

基本的なatoi関数の利用方法

それでは、一番基本となるatoi関数を呼び出してみましょう。引数に「数字」である”123456″の文字列をポインタで受け渡します。

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

int main(void)
{
	char * input = "123456";	//	入力となる数字
	int	num = 0;

	//	数字を数値に変換
	num = atoi(input);

	printf("%d", num);

	return 0;
}
123456

結果はこの通り、文字である数字から計算可能な数値へ変換することができました。

スポンサーリンク

atoi関数のサンプルコード:様々な入力文字列に対する出力結果

このようなライブラリ関数を使う時には、気をつけるべきことがあります。

それは、様々な入力パターンの文字や数字を「引数」で渡したときに、どのような「戻り値」の結果を受け取れるかをしっかりと把握することです。

入力ケースに対する出力の把握

これを把握しておかないと、意図せぬ動作になって場合によっては大きな問題となります。

入力サンプルに対する結果

それでは実際に様々な入力ケースに対するatoi関数の変換結果を考察しましょう。

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

int main(void)
{
	printf("%s => %d\n", "-123",	atoi("-123"));
	printf("%s => %d\n", "3.14",	atoi("3.14"));
	printf("%s => %d\n", "XYZ",		atoi("XYZ"));
	printf("%s => %d\n", "5G",		atoi("5G"));
	printf("%s => %d\n", "G5",		atoi("G5"));
	printf("%s => %d\n", "1 2 3",	atoi("1 2 3"));
	printf("%s => %d\n", "    1",	atoi("    1"));
	printf("%s => %d\n", "1,2,3",	atoi("1,2,3"));

	return 0;
}
-123 => -123
3.14 => 3
XYZ => 0
5G => 5
G5 => 0
1 2 3 => 1
    1 => 1
1,2,3 => 1

この結果から、atoi関数の基本的な設計思想を読み取っていきます。

入力文字列出力結果考察内容
-123-123負値は正常に変換される。
3.143小数点以下は切り捨て。整数型のため妥当な結果。
XYZ0英字は変換できない。異常として0を出力する。
5G5数字がある場合は、数字の部分だけ変換する。
G50英字の後の数字は認識できない。異常として0を出力する。
1 2 31スペースの区切りが出現したら変換は終了する。
  11先頭のスペースは無視されて変換される。
1,2,31カンマのような記号も出現したら変換は終了する。

特徴的なのは、「数値」に変換できない文字が出現したときの動作ですね。

先頭から文字を変換し、変換できない文字が出現した時点で変換を終了していることが想像できます。

ただし、先頭のスペースに関しては特別に無視するという特殊処理となっていますね。

変換異常時の取り扱いに注意

atoi関数の仕様の性質上、注意するべき点があります。それは「変換異常時に0を返却」するということです。

入力パターンとして “0” という入力もあり得るわけですから、正常な変換結果の「0」と変換異常時の「0」の見分けが付きません。

異常と正常が区別できない

このような判別できないケースも含めて、成立するプログラムを組み立てる必要があります。

スポンサーリンク

atof関数のサンプルコード:様々な入力文字列に対する出力結果

続けて、浮動小数点の数字を数値に変換するatof関数も同様に動作を確認しておきましょう。

入力サンプルに対する結果

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

int main(void)
{
    printf("%s => %lf\n", "-123.4",         atof("-123.4"));
    printf("%s => %lf\n", "3.14",           atof("3.14"));
    printf("%s => %lf\n", "XYZ",            atof("XYZ"));
    printf("%s => %lf\n", "5.5G",           atof("5.5G"));
    printf("%s => %lf\n", "G5.5",           atof("G5.5"));
    printf("%s => %lf\n", "1.5 2.5 3.5",    atof("1.5 2.5 3.5"));
    printf("%s => %lf\n", "        1.5",    atof("        1.5"));
    printf("%s => %lf\n", "1.5,2.5,3.5",    atof("1.5,2.5,3.5"));

    return 0;
}
-123.4 => -123.400000
3.14 => 3.140000
XYZ => 0.000000
5.5G => 5.500000
G5.5 => 0.000000
1.5 2.5 3.5 => 1.500000
        1.5 => 1.500000
1.5,2.5,3.5 => 1.500000

atof関数の結果はatoiと大きく変わったところはありません。

入力文字列出力結果考察内容
-123.4-123.400000負値は正常に変換される。
3.143.140000小数点以下も正常に変換できる。
XYZ0.000000英字は変換できない。異常として0.0を出力する。
5.5G5.500000数字がある場合は、数字の部分だけ変換する。
G5.50.000000英字の後の数字は認識できない。異常として0.0を出力する。
1.5 2.5 3.51.500000スペースの区切りが出現したら変換は終了する。
   1.51.500000先頭のスペースは無視されて変換される。
1.5,2.5,3.51.500000カンマのような記号も出現したら変換は終了する。
スポンサーリンク

atoi関数とsscanf関数の使い分け

実は数字を数値に変換する方法には、atoi関数以外にもsscanf関数を使う方法があります。

sscanf関数はかなりリッチな機能を備えており、文字列の中から英字と数字を切り分けたり、16進数の数字を数値に変換することもできます。

atoi関数のメリット・デメリット
  • 関数の入出力がシンプルなため、扱い方が簡単。
  • 異常時の扱い方に注意が必要。
  • 簡単な数字のみが変換でき、複雑な文字列は変換できない。
sscanf関数のメリット・デメリット
  • 文字や数字が入り乱れた文字列も、切り分けながら変換ができる。
  • スペース区切りやカンマ区切りの複数の数字も一括変換が可能。
  • 16進数の変換も可能。
  • atoi関数に比べると入出力が複雑で扱うのが難しい。
ナナ
ナナ

C言語は文字列を扱うのが苦手なため、複雑な文字列を操作する際は「sscanf関数」のような高機能関数を使うとバグの発生を軽減できます。