Arduino環境(ESP32, M5Stack)で、文字列(String)と整数(int)の変換方法について説明します。
Arduino環境(ESP32, M5Stack)では、int は4バイトとなります。ちなみに、longも4バイトです。
C言語の int
型のサイズは、規格上では定められていません。一般的には、使用するCPU/MPUのビット数やレジスタのビット数に依存しますが、具体的なサイズはコンパイラや開発環境によって異なります。そのため、C/C++言語を使用する際は、常に利用環境における int
型のサイズを確認することが重要です。
より厳密なサイズ指定が必要な場合は、stdint.h
ヘッダで定義されている int16_t
、int32_t
、int64_t
などの型を使用することを推奨します。これらの型は、それぞれ16ビット、32ビット、64ビットの整数を保証します。
整数(int)から、文字列(String)への変換
整数値を文字列に変換する方法には、以下の3通りの方法があります。
String()を使用
String()を使用する事で、整数を文字列(String)に変換できます。
8バイトの整数(int64_t, uint64_t)や、float、doubleの変換にも対応しています。String()を使用するのが最も簡単です。
構文
String(val)
String(val, base)
// float, doubleの変換も可能です。
String(float) // float を String に変換
String(float, 桁数) // 小数点以下の桁数を指定
// ----------------------------------------------
double d = 3.14159265358979323846;
String str1 = String(d); // デフォルトの桁数で変換
String str2 = String(d, 4); // 小数点以下4桁で変換
String str3 = String(d, 10); // 小数点以下10桁で変換
例
String stringOne = "Hello String"; // 文字列定数を使用
String stringOne = String('a'); // 1文字
String stringTwo = String("This is a string");
String stringOne = String(stringTwo + " with more"); // 連結
String stringOne = String(13); // 定数
String stringOne = String(analogRead(0), DEC); // 整数(10進数)
String stringOne = String(45, HEX); // 整数(16進数)
String stringOne = String(255, BIN); // 整数(2進数)
String stringOne = String(millis(), DEC); // long型整数
void setup() {
Serial.begin(115200);
// `itoa()` の使用例(符号付き)
int num1 = -12345;
itoa(num1, buffer, 10);
Serial.print("itoa: ");
Serial.println(String(num1, DEC));
// `utoa()` の使用例(符号なし)
unsigned int num2 = 12345;
utoa(num2, buffer, 10);
Serial.print("utoa: ");
Serial.println(String(num2, DEC));
// `ltoa()` の使用例(符号付き long)
long num3 = -2147483647;
ltoa(num3, buffer, 10);
Serial.print("ltoa: ");
Serial.println(String(num3, DEC));
// `ultoa()` の使用例(符号なし long)
unsigned long num4 = 4294967295;
ultoa(num4, buffer, 10);
Serial.print("ultoa: ");
Serial.println(String(num4, DEC));
// `lltoa()` の使用例(符号付き long long)
long long num5 = -9223372036854775807LL;
lltoa(num5, buffer, 10);
Serial.print("lltoa: ");
Serial.println(String(num5, DEC));
// `ulltoa()` の使用例(符号なし long long)
unsigned long long num6 = 18446744073709551615ULL;
ulltoa(num6, buffer, 10);
Serial.print("ulltoa: ");
Serial.println(String(num6, DEC));
// 16進数(Hex)変換の例
itoa(num1, buffer, 16);
Serial.print("itoa (hex): ");
Serial.println(String(num1, HEX));
}
C言語の標準関数を使用
以下の、C言語の標準関数を使用する事で整数値を文字列(C言語の文字列)に変換することができます。
関数 | バイト数 | 符号 |
---|---|---|
itoa() | 4バイト(32bit) | 符号付き |
utoa() | 4バイト(32bit) | 符号無し |
ltoa() | 4バイト(32bit) | 符号付き |
ultoa() | 4バイト(32bit) | 符号無し |
lltoa() | 8バイト(64bit) | 符号付き |
ulltoa() | 8バイト(64bit) | 符号無し |
dtostrf () | float/double | 第2引数:全体の長さ 第3引数:少数点以下の桁数 |
例
void setup() {
Serial.begin(115200);
char buffer[32]; // 変換結果を格納するバッファ
// `itoa()` の使用例(符号付き)
int num1 = -12345;
itoa(num1, buffer, 10);
Serial.print("itoa: ");
Serial.println(buffer);
// `utoa()` の使用例(符号なし)
unsigned int num2 = 12345;
utoa(num2, buffer, 10);
Serial.print("utoa: ");
Serial.println(buffer);
// `ltoa()` の使用例(符号付き long)
long num3 = -2147483647;
ltoa(num3, buffer, 10);
Serial.print("ltoa: ");
Serial.println(buffer);
// `ultoa()` の使用例(符号なし long)
unsigned long num4 = 4294967295;
ultoa(num4, buffer, 10);
Serial.print("ultoa: ");
Serial.println(buffer);
// `lltoa()` の使用例(符号付き long long)
long long num5 = -9223372036854775807LL;
lltoa(num5, buffer, 10);
Serial.print("lltoa: ");
Serial.println(buffer);
// `ulltoa()` の使用例(符号なし long long)
unsigned long long num6 = 18446744073709551615ULL;
ulltoa(num6, buffer, 10);
Serial.print("ulltoa: ");
Serial.println(buffer);
// 16進数(Hex)変換の例
itoa(num1, buffer, 16);
Serial.print("itoa (hex): ");
Serial.println(buffer);
// float型の値を文字列に変換
float floatValue = 123.45;
dtostrf(floatValue, 6, 2, buffer);
Serial.print("dtostrf(float) : ");
Serial.println(buffer);
// double型の値を文字列に変換
double doubleValue = 123.45;
dtostrf(doubleValue, 6, 2, buffer);
Serial.print("dtostrf(double): ");
Serial.println(buffer);
}
sprintf を使用
C言語の標準関数 sprintf関数を使用して、整数値を文字列(C言語の文字列)に変換する事ができます。
構文
#include <stdio.h>
int sprintf(char *str, const char *format, ...);
フォーマット指定子
以下、フォーマット指定子の一覧です。
データ型 | ビット数 | 符号 | フォーマット指定子 | 必要なバッファサイズ |
---|---|---|---|---|
int16_t | 16bit | 符号付き | %d | 7 |
uint16_t | 16bit | 符号なし | %u | 6 |
int32_t(int,long) | 32bit | 符号付き | %d または %ld | 12 |
uint32_t(unsigned int, unsigned long) | 32bit | 符号なし | %u または %lu | 11 |
int64_t(long long) | 64bit | 符号付き | %lld | 21 |
uint64_t(unsigned long long) | 64bit | 符号なし | %llu | 21 |
文字列(String)から、整数(int)への変換
toint()関数
文字列(String)から整数への変換には、toint()関数を使用します。(String.toInt())変換できない場合は0を返します。
それから、C言語の標準関数(ヘッダファイル:stdlib.h)の
strtol()
、及びstrtoul() を使用することもできます。これからの関数は、基数(2進数、10進数、16進数など)を指定する事ができますので、16進も文字列を整数に変換する時は便利です。(0: オプション 先行符号の後、先行 0 は 8 進変換を示し、先行 0x または 0X は 16 進変換を示し、それ以外は10進変換となります。)
構文
long String::toInt(void) const;
戻り値
変換後の数値で、long(4バイト)値です。整数値で始まらない文字列を変換しようとしたときは、0が返却される。
例
String wstr = "123";
long ldata = wstr.toInt();
C言語の標準関数を使用
以下の関数を使用する事で、文字列から整数への変換が可能です。
目的 | 関数 | 返す型 | ESP32での型 |
---|---|---|---|
符号付き 32ビット整数 | atoi() | int | int32_t |
符号付き 32ビット整数 | atol() | long | int32_t |
符号付き 64ビット整数 | atoll() | long long | int64_t |
符号付き 32ビット整数 | strtol() | long | int32_t |
符号付き 64ビット整数 | strtoll() | long long | int64_t |
符号なし 32ビット整数 | strtoul() | unsigned long | uint32_t |
符号なし 64ビット整数 | strtoull() | unsigned long long | uint64_t |
float/double | atof() | double | double |
文字列(String)から、8バイト(64ビット)の整数への変換
文字列(String)から、8バイト(64ビット)の整数への変換には、C言語の標準関数(ヘッダファイル:stdlib.h)の
strtoll()
、及びstrtoull() を使用します。
尚、これからの関数は、基数(2進数、10進数、16進数など)を指定する事ができます。
符号付きの 8 バイト整数(int64_t
)に変換するには strtoll()
を使用します。
String strNumber = "-987654321012345678"; // 負の数の例
int64_t num = strtoll(strNumber.c_str(), NULL, 10); // 10進数として変換
符号なしの 8 バイト整数(uint64_t
)に変換するにはstrtoull()
を使用します。
String strNumber = "1234567890123456789"; // 例: 19桁の数値
uint64_t num = strtoull(strNumber.c_str(), NULL, 10); // 10進数として変換
基数(2進数、10進数、16進数など)を指定できます。
sscanf
sscanf()
関数を使用すると、より柔軟な変換が可能です。例えば、文字列から複数の整数を抽出したり、特定の形式の文字列を変換したりできます。
以下、各データサイズのフォーマット指定子の一覧です。
データ型 | サイズ | フォーマット指定子 |
---|---|---|
int8_t | 1バイト | %hhd |
int16_t | 2バイト | %hd |
int32_t | 4バイト | %d |
int64_t | 8バイト | %lld |
uint8_t | 1バイト | %hhu |
uint16_t | 2バイト | %hu |
uint32_t | 4バイト | %u |
uint64_t | 8バイト | %llu |
float | – | %f |
double | – | %lf |
例
以下、sscanfを使用したサンプルコードです。
#include <stdio.h>
String strNum = "-128 32767 2147483647 -9223372036854775808";
int8_t num1;
int16_t num2;
int32_t num4;
int64_t num8;
int matched = sscanf(strNum.c_str(), "%hhd %hd %d %lld", &num1, &num2, &num4, &num8);
if (matched == 4) {
Serial.print("int8_t: ");
Serial.println(num1);
Serial.print("int16_t: ");
Serial.println(num2);
Serial.print("int32_t: ");
Serial.println(num4);
Serial.print("int64_t: ");
Serial.println(num8);
} else {
Serial.println("Conversion error!");
}
まとめ
以下、文字列(String)から、整数(int)への変換について簡単に表にまとめます。
関数 | 2バイト(int16_t) | 4バイト(int32_t) | 8バイト(int64_t) | エラー判定 | 特徴 |
---|---|---|---|---|---|
toInt() | ○(キャスト必要) | ○ | × | × | 簡単・Arduino標準 |
atol() | × | ○ | × | × | C言語標準・簡単 |
atoll() | × | × | ○ | × | C言語標準・簡単 |
strtol() | × | ○ | × | ○ | エラーチェック可能 |
strtoll() | × | × | ○ | ○ | エラーチェック可能 |
sscanf() | ○ | ○ | ○ | △ | 複数の数値を一度に取得 |
それぞれの特徴
- 手軽に変換したいなら toInt()(4バイトまで)
- 8バイト整数が必要なら atoll()
- エラーチェックしたいなら strtol() / strtoll()
- 複数の数値を一度に変換したいなら sscanf()
文字列(String)から、floatへの変換
文字列から、floatへの変換には、toFloat()関数を使用します。また、atof()関数、またはstrtof()関数を使用することもできます。
構文
float String::toFloat(void) const;
戻り値
変換後の浮動小数です。数値で始まらない文字列を変換しようとしたときは、0が返ります。
文字列(String)から、doubleへの変換
文字列から、floatへの変換には、toDouble()関数を使用します。また、atof()関数、またはstrtod()関数を使用することもできます。
書式
double String::toDouble(void) const;
戻り値
変換後の浮動小数。数値で始まらない文字列を変換しようとしたときは、0が返却されます。
データ型と対応する printf のフォーマット指定子
ESP32 の printf()
は 標準 C の printf()
に対応している ので、通常のフォーマット指定子を使用できます。M5.Lcd(M5.Display)のprintf()でも使用できます。
データ型 | ビット数 | 符号 | フォーマット指定子 |
---|---|---|---|
int16_t | 2バイト(16bit) | 符号付き | %d または %hd |
uint16_t | 2バイト(16bit) | 符号なし | %u または %hu |
int32_t(int,long) | 4バイト(32bit) | 符号付き | %d または %ld |
uint32_t(unsigned int, unsigned long) | 4バイト(32bit) | 符号なし | %u または %lu |
int64_t(long long) | 8バイト(64bit) | 符号付き | %lld |
uint64_t(unsigned long long) | 8バイト(64bit) | 符号なし | %llu |
符号なし16進数(小文字) | 符号なし | %x | |
符号なし16進数(大文字) | 符号なし | %X | |
float/double | %f(%.2fで、小数点以下2桁表示) |
参考URL
以下のURLの参考にしてください。