2025/01/09 多機能画像スクリーンセーバー KScrn32/KScrn64(フリー版、シェアウェア版)をVectorで公開

String と int の変換(ESP32)

ESP32

Arduino環境(ESP32, M5Stack)で、文字列(String)と整数(int)の変換方法について説明します。

Arduino環境(ESP32, M5Stack)では、int は4バイトとなります。ちなみに、longも4バイトです。

C言語の int 型のサイズは、規格上では定められていません。一般的には、使用するCPU/MPUのビット数やレジスタのビット数に依存しますが、具体的なサイズはコンパイラや開発環境によって異なります。そのため、C/C++言語を使用する際は、常に利用環境における int 型のサイズを確認することが重要です。

より厳密なサイズ指定が必要な場合は、stdint.h ヘッダで定義されている int16_tint32_tint64_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_t16bit符号付き%d7
uint16_t16bit符号なし%u6
int32_t(int,long)32bit符号付き%d または %ld12
uint32_t(unsigned int, unsigned long)32bit符号なし%u または %lu11
int64_t(long long)64bit符号付き%lld21
uint64_t(unsigned long long)64bit符号なし%llu21

文字列(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()intint32_t
符号付き 32ビット整数atol()longint32_t
符号付き 64ビット整数atoll()long longint64_t
符号付き 32ビット整数strtol()longint32_t
符号付き 64ビット整数strtoll()long longint64_t
符号なし 32ビット整数strtoul()unsigned longuint32_t
符号なし 64ビット整数strtoull()unsigned long longuint64_t
float/doubleatof()doubledouble

文字列(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_t1バイト%hhd
int16_t2バイト%hd
int32_t4バイト%d
int64_t8バイト%lld
uint8_t1バイト%hhu
uint16_t2バイト%hu
uint32_t4バイト%u
uint64_t8バイト%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_t2バイト(16bit)符号付き%d または %hd
uint16_t2バイト(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の参考にしてください。

タイトルとURLをコピーしました