https://youtu.be/iRyUV-mJ57M

\textcolor{pink}{四国めたん: }教師役ですわ

\textcolor{lime}{ずんだもん: }生徒役なのだ
\footnotesize \textcolor{pink}{四国めたん:} 皆さん、こんにちは。四国めたんです
\footnotesize \textcolor{lime}{ずんだもん:} ずんだもんなのだ。こんにちはなのだ
\footnotesize \textcolor{pink}{四国めたん:} 今回もC言語のお勉強をしていきましょう
\footnotesize \textcolor{lime}{ずんだもん:} レッツゴーなのだ
\footnotesize \textcolor{pink}{四国めたん:} 今まで、整数や浮動小数点数などの数値、そして文字や文字列についてお話ししてきましたわ
\footnotesize \textcolor{lime}{ずんだもん:} int型やfloat型、** double型**、そしてchar型の配列などなのだ
\footnotesize \textcolor{pink}{四国めたん:} 今回は数値を文字列に、文字列を数値に変換するお話しをしますわ
\footnotesize \textcolor{lime}{ずんだもん:} よろしくお願いするのだ
数値を文字列に
\footnotesize \textcolor{pink}{四国めたん:} まずは数値を文字列に変換しますわ
\footnotesize \textcolor{lime}{ずんだもん:} 数値というと整数だけではなく、浮動小数点数も含むのか?
\footnotesize \textcolor{pink}{四国めたん:} はい、そして数値を文字列として出力する関数は、今までも使ってきましたわ
\footnotesize \textcolor{lime}{ずんだもん:} printf
やfprintf
関数で出力できていたのだ
\footnotesize \textcolor{pink}{四国めたん:} 出力先がコンソールやファイルでしたが、その通りですわ
\footnotesize \textcolor{pink}{四国めたん:} 今回は、数値を文字列に変換するために、char型の配列、つまりメモリ上に出力しますわ
\footnotesize \textcolor{lime}{ずんだもん:} どのように出力するのだ?
\footnotesize \textcolor{pink}{四国めたん:} はい、snprintf
という関数を使いますわ
\footnotesize \textcolor{lime}{ずんだもん:} どのような関数なのだ
\footnotesize \textcolor{pink}{四国めたん:} 形式はint snprintf(char* str, size_t num, const char* format, ... )
となりますわね
\footnotesize \textcolor{lime}{ずんだもん:} 詳しく教えてほしいのだ
\footnotesize \textcolor{pink}{四国めたん:} まず、"str"には、変換後の文字列が入りますわ
\footnotesize \textcolor{lime}{ずんだもん:} char型の配列やmalloc
などで確保したメモリ領域でもだいじょうぶなのか?
\footnotesize \textcolor{pink}{四国めたん:} そうですわね
\footnotesize \textcolor{pink}{四国めたん:} 次に"num"にはセットしたメモリ領域のサイズをバイト単位で指定しますわ
\footnotesize \textcolor{pink}{四国めたん:} なお、配列のサイズやメモリ領域のサイズについては、NUL終端も含めて十分な大きさが必要ですわ
\footnotesize \textcolor{lime}{ずんだもん:} サイズが不十分な場合にはどうなるのだ?
\footnotesize \textcolor{pink}{四国めたん:} 変換後の文字列が途切れますわね
\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ
\footnotesize \textcolor{pink}{四国めたん:} 次に、"format"に書式指定子のみを記述すれば、数値がそのまま文字列になりますわ
\footnotesize \textcolor{lime}{ずんだもん:} "format"には書式指定子以外の文字列も設定できるのか?
\footnotesize \textcolor{pink}{四国めたん:} はい、printf
などと同じく、"format"には書式指定子以外の文字列も設定できますわ
\footnotesize \textcolor{pink}{四国めたん:} その場合には、"format"に設定した文字列は、そのままchar型の配列にコピーされますわ
\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ
\footnotesize \textcolor{lime}{ずんだもん:} 戻り値はなにが返るのだ?
\footnotesize \textcolor{pink}{四国めたん:} 戻り値は出力された文字数ですわ
\footnotesize \textcolor{lime}{ずんだもん:} 関数が失敗した場合にはどうなるのだ?
\footnotesize \textcolor{pink}{四国めたん:} 関数が失敗した場合には、負数が返りますわね
\footnotesize \textcolor{pink}{四国めたん:} とりあえず実際の例を見てみましょう
#include <stdio.h>
#define SIZE (20)
void main() {
char integer[SIZE] = {0};
char decimal[SIZE] = {0};
int x = 1234;
double y = 567.89;
snprintf(integer, SIZE, "%d", x);
snprintf(decimal, SIZE, "%f", y);
printf("%s\n", integer);
printf("%s\n", decimal);
}

\footnotesize \textcolor{lime}{ずんだもん:} 「1234」, 「567.890000」と表示されたのだ
\footnotesize \textcolor{pink}{四国めたん:} はい、しっかりと数値が文字列に変換されていますわね
\footnotesize \textcolor{lime}{ずんだもん:} 解説をおねがいするのだ
\footnotesize \textcolor{pink}{四国めたん:} はい、まず文字列を格納する配列のサイズは20としていますわ
\footnotesize \textcolor{lime}{ずんだもん:} 20で足りるのか?
\footnotesize \textcolor{pink}{四国めたん:} 数値を書き出すのには十分なサイズですわ
\footnotesize \textcolor{pink}{四国めたん:} ただ、出力からわかる通り、浮動小数点数の場合は指定した数値よりも桁数が多くなる場合がありますわ
\footnotesize \textcolor{lime}{ずんだもん:} 浮動小数点数を文字列に変換する場合には、配列のサイズを大きめに取っておくのだ
\footnotesize \textcolor{pink}{四国めたん:} 特に浮動小数点数を**指数表記**で扱う場合には注意が必要ですわ
\footnotesize \textcolor{lime}{ずんだもん:} わかったのだ
snprintfは便利です
snprintf
は、数値を文字列に変換することに使える関数です
ですが、それ以上に便利に使える関数です
例えばネットワークを通してデータを送信する際、多くは文字列を使用します
それらの文字列は、状況によって変化しますので、都度、作成する必要があります
その時、活躍するのがsnprintf
です
文字列を数値に
\footnotesize \textcolor{pink}{四国めたん:} 次に文字列を数値に変換するお話しをしますわ
\footnotesize \textcolor{lime}{ずんだもん:} おねがいするのだ
\footnotesize \textcolor{pink}{四国めたん:} まず、変換する文字列は、整数や浮動小数点数などの数値を表現している必要がありますわ
\footnotesize \textcolor{lime}{ずんだもん:} 数値以外の文字が含まれている場合にはどうなるのだ?
\footnotesize \textcolor{pink}{四国めたん:} どのような文字かにもよりますが、正しく変換できない場合が多いですわ
\footnotesize \textcolor{lime}{ずんだもん:} 数値以外の文字は含まないように気を付けるのだ
\footnotesize \textcolor{pink}{四国めたん:} 文字列を数値に変換するための関数は多くありますが、今回は3つの関数を取り上げますわ
-
int atoi(const char* str)
: 文字列をint型の整数に変換する
-
long atol(const char* str)
: 文字列をlong型の整数に変換する
-
double atof(const char* str)
: 文字列をdouble型の浮動小数点数に変換する
\footnotesize \textcolor{pink}{四国めたん:} なお、これらの関数を使う場合には"stdlib.h"ファイルをインクルードする必要がありますわ
\footnotesize \textcolor{lime}{ずんだもん:} 最初に#include <stdlib.h>
を記述するのだ
\footnotesize \textcolor{pink}{四国めたん:} 引数の"str"には変換する文字列をセットしますわ
\footnotesize \textcolor{lime}{ずんだもん:} 変換に失敗した場合にはどうなるのだ?
\footnotesize \textcolor{pink}{四国めたん:} 0もしくは0.0が返りますわね
\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ
\footnotesize \textcolor{lime}{ずんだもん:} ところでatoi
は"ascii to integer"の略なのか?
\footnotesize \textcolor{pink}{四国めたん:} そうですわね
\footnotesize \textcolor{pink}{四国めたん:} そして、atol
は"ascii to long integer"の略ですわね
\footnotesize \textcolor{lime}{ずんだもん:} atof
は"ascii to floating point number"の略か...
\footnotesize \textcolor{pink}{四国めたん:} はい、戻り値はdouble型ですけど...
\footnotesize \textcolor{pink}{四国めたん:} とりあえず実際の例を見てみましょう
#include <stdio.h>
#include <stdlib.h>
void main() {
char integer[] = "123456";
char decimal[] = "0.123456";
int x = atoi(integer);
long y = atol(integer);
double z = atof(decimal);
printf("%d\n", x);
printf("%ld\n", y);
printf("%lf\n", z);
}

\footnotesize \textcolor{lime}{ずんだもん:} 「123456」、「123456」、「0.123456」と表示されたのだ
\footnotesize \textcolor{pink}{四国めたん:} はい、文字列"123456"と"0.123456"を数値に変換できましたわ
\footnotesize \textcolor{lime}{ずんだもん:} ところで"%ld"や"%lf"はなんなのだ?
\footnotesize \textcolor{pink}{四国めたん:} printf
の書式指定子"%ld"はlong型を、"%lf"はdouble型を表示しますわ
数値に変換可能な文字列
文字列を数値に(他の関数)
文字列を浮動小数点数に変換する他の関数は、strtof
やstrtod
、strtold
があります
形式は以下の通りです
-
float strtof(const char* str, char** endptr)
: 文字列をfloat型の浮動小数点数に変換する
-
double strtod(const char* str, char** endptr)
: 文字列をdouble型の浮動小数点数に変換する
-
long double strtold(const char* str, char** endptr)
: 文字列をlong double型の浮動小数点数に変換する
変換対象の文字列を"str"にセットします
"endptr"には、変換後の残りの文字列が返ります
通常はNULLをセットして問題ないと思います
また、文字列を整数に変換する他の関数は、strtol
やstrtoll
、strtoul
、strtoull
があります
形式は以下の通りです
-
long strtol(const char* str, char** endptr, int base)
: 文字列をlong型の整数に変換する
-
long long strtoll(const char* str, char** endptr, int base)
: 文字列をlong long型の整数に変換する
-
unsigned long strtoul(const char* str, char** endptr, int base)
: 文字列をunsigned long型の整数に変換する
-
unsigned long long strtoull(const char* str, char** endptr, int base)
: 文字列をunsigned long long型の整数に変換する
変換対象の文字列を"str"にセットします
"endptr"には、変換後の残りの文字列が返ります
通常はNULLをセットして問題ないと思います
"base"は、これらの関数のもっとも特徴的な引数で、変換時の基数を指定します
10進数であれば10ですが、16進数では16、8進数では8、2進数では2などを指定できます
これらはatoi
やatol
にはない特徴で、意外に便利です
まとめ
\footnotesize \textcolor{pink}{四国めたん:} お疲れさまでした
\footnotesize \textcolor{lime}{ずんだもん:} おつかれさまなのだ
\footnotesize \textcolor{pink}{四国めたん:} 以上で数値と文字列の変換についての説明は終わりですわ
Discussion