第22回 Stringクラス

前回の記事作成したスケッチには改良の余地がありますので、これからその対応を行うことにより新しい知識を身につけます!

目次

改良の余地?

前回の記事で「言い訳キーボード」として動作するスケッチが(とりあえず)完成しました。

これで一通り終わり…といきたいところですが、もう少しお付き合いください。

この記事の冒頭で「スケッチには改良の余地がある」と説明しました。「改良の余地」というのは「文字列の扱い方」なんです。

そこで、これから文字列の扱い方を改良することにより新しい知識を身につけていきます。


Arduinoで電子工作を進めていくと「文字列」を扱うことが多くなってきます。

例えば、次のような文字が表示できる「液晶モジュール」という部品が売られています。

液晶モジュール

それほど高価なものではないので(500〜1,000円程度)、Arduinoの電子工作で何か文字を表示したい時に気軽に使えます。

例えば、センサで測定した気温や湿度を表示したり、ゲームの得点を表示することができるので、作れるものが広がりそうですよね。

この液晶モジュールでは当然ながら文字列を表示するので、スケッチでは文字列の処理が必要になります。

また言い訳キーボードでも文字列を扱いますので、これから文字列の扱い方をもう少し深く習得することにします。

C言語の文字列とArduinoの文字列

これから「文字列の扱い方」を説明していきますが、C++言語ではなく、Arduino専用の文字列の扱い方になります。

もしかしたらご存知の方もいるかもしれませんが、C++言語で文字列を扱うにはかなり難しい知識が必要になってしまうんです。C++言語で文字列を扱おうとすると、その知識の説明のために1つのシリーズ記事になってしまうほどです。

ArduinoはC++言語をベースにしていますが、簡単に電子工作&プログラミングができるように開発されたシステムです。

そのため、Arduinoでは文字列も扱いやすいようにArduino専用の仕組みが用意されています。


この仕組ですが、文字列が簡単に扱える「ライブラリ」(クラス)が提供されています。このライブラリはシステムにデフォルトで入っていますのですぐに使えます。

今回と次回の記事ではその文字列を扱うライブラリについて習得していきます。


ところで、習得する文字列の扱い方はArduino専用なので、他のプログラミング言語を習得するときにまた新しいことを覚える必要が出てくるのではないか、と心配になってしまうかもしれません。

でも安心してください。

PythonやJavaScriptなどの人気のあるプログラミング言語の文字列の扱い方は、Arduinoの文字列の扱い方にかなり似ています。

Arduinoの文字列処理を一度経験したあと、Pythonのプログラムを見ると「あれ?どこかでみたことがある?」って感じになると思います。

逆にC++言語のような文字列の扱い方をするプログラミング言語は少数派なんです。

ということで、Arduinoの文字列の扱い方を習得していきましょう!

Stringクラス

Arduinoでは文字列を簡単に扱うことができるように「Stringクラス」が用意されています。

「String」とは、日本語で「文字列」という意味です。そのものって感じですね。

デフォルトで利用できますので、ヘッダファイルをインクルードする必要はありません。

これから、Stringクラスの使い方を見ていきます。

Stringクラスのインスタンス生成

Arduinoの文字列処理はStringクラスを使用しますので、クラスからインスタンスを生成する必要があります。

そこでStringクラスの説明に入る前に、以前出てきたSwitchクラスのインスタンス生成について復習しておきましょう。

このように書くと、意味としては「Switchというクラス(型)でhidariSwitchという名前のインスタンス(スケッチ上で扱う部品)を生成してください。実際のスイッチはA5端子に接続しています」という意味になりました。

ここで注目していただきたい点があります。

それはhidariSwitchというインスタンスを生成するときに、引数は実際のスイッチが接続されている端子名であったことです。

これから、Stringクラスのインスタンスを生成する方法を説明しますが、当然ながら引数はSwitchクラスと異なります。この点に注意して読み進めてみてください。


最初のStringクラスのインスタンス生成方法は、次のような書き方です。

分かりづらいので具体例でみていきましょう!

Stringクラスのインスタンス例

このようにスケッチに書いた場合、"okitara"という文字データを持つ、iiwakeという名前のインスタンス(オブジェクト)を作ることができます。

あとは、iiwakeというインスタンスに対して、次のようにメソッドを指定して操作することになります。

String iiwake( "okitara" );  // 文字列インスタンス生成

iiwake.メソッド名();  // iiwakeという文字列をメソッドで操作

ところで、上のStringクラスの説明で、「値が数値の場合は、その数値の文字列を生成する」と書いてありますが、正直、よく分かりませんよね。

数値と文字列の違いについては記事の後半で具体例で説明しますので参考にしてみてください。


う〜ん、これだけだと何をしたいのかよくわからないですし、何が便利なのかもよくわからないですよね。

それでは、これから具体的に生成したインスタンスの使い方を見ていきましょう。

Stringクラスのメソッド

先ほど、以下のようにStringクラスのインスタンスを生成しました。

String iiwake( "okitara" );

このように書くと、iiwakeというインスタンスを普通の文字列のように扱うことができます。

例えば、以下のようにシリアルモニタを使用することができます。

String iiwake( "okitara" );  // "okitara"という文字データのiiwakeを生成

Serial.println( iiwake );  // iiwakeをシリアルモニタに表示

このスケッチを実行すると、シリアルモニタには以下のようにiiwakeの文字データ"okitara"が表示されます。

okitara

また、クラスから生成したインスタンスですので、メソッドも用意されています。

iiwakeというインスタンスは"okitara"という文字列ですが、この文字列に" atamaga itainode"という文字列を追加したい場合は「concat」というメソッドを使用します。「concat」とは日本語で「連結する」という意味です。

concatメソッドは次のように使用します。

String iiwake( "okitara" );  // "okitara"という文字データのiiwakeを生成

iiwake.concat( " atamaga itainode" ); // iiwakeの文字データに" atamaga itainode"を追加

このようにconcatメソッドを使うと、iiwakeの文字データは"okitara atamaga itainode"となります。

次のスケッチは、concatで操作した結果をシリアルモニタに表示する内容です。

String iiwake( "okitara" );  // "okitara"という文字データのiiwakeを生成

iiwake.concat( " atamaga itainode" ); // iiwakeの文字データに" atamaga itainode"を追加

Serial.println( iiwake );  // iiwakeの文字データをシリアルモニタに表示

このスケッチを実行すると以下のようになります。

okitara atamaga itainode

スケッチの1行目でStringクラスからiiwakeというインスタンス名で、"okitara"という文字列のインスタンスを生成します。

3行目では、concatメソッドを使用してiiwakeインスタンスに" atamaga itainode"という文字列を追加(後ろに連結)します。

5行目でその文字列を表示しますので、シリアルモニタにはokitara atamaga itainodeと表示されます。

文字列の「123」と数値の「123」の違い

ところで、Stringクラスのインスタンス生成のところで、「引数が数値の場合は、その数値の文字列を生成する」と説明しました。

文字列の「123」と数値の「123」って違いがよくわからないですよね。

そこで、具体的なスケッチで両者の違いを確認します。

String moji(123);  // 「moji」というインスタンスは、文字列データの「123」になる
uint16_t suuji = 123;  // 「suuji」というuint16_t型の変数は、数値データの「123」になる

Serial.println( moji );
Serial.println( suuji );

このスケッチの場合、シリアルモニタには以下のよう表示されます。

123
123

文字列データの「123」も数値データの「123」も見分けがつきませんよね。


この例では何が違うのかよくわかりませんが、「足し算」をすると差が出てきます。

次のように文字列データと数値データを足し算するようなスケッチがどうなるかみてみましょう。

String moji_1(123);  // 「123」の文字列データのインスタンスを生成
String moji_2(456);  // 「456」の文字列データのインスタンスを生成

uint16_t  suuji_1 = 123;  // 123の数値データの変数を宣言
uint16_t  suuji_2 = 456;  // 456の数値データの変数を宣言

Serial.println( moji_1 + moji_2 );    // 文字列データの足し算
Serial.println( suuji_1 + suuji_2 );  // 数値データの足し算

このスケッチを実行すると、シリアルモニタには次のように表示されます。

123456
579

スケッチの7行目では、「123」と「456」の文字列データを足し算しています。文字列データの足し算は単に連結するだけになります。

8行目では、数値「123」と「456」の足し算になりますので、算術計算となり、結果は 123+456 = 579 という結果になります。

ちょっとややこしい話ですので、頭の片隅に置いておいていただければと思います。

Stringクラスのいいところ

ところで、Stringクラスの使い方をいろいろと説明してきましたが、何かいいことあるのでしょうか。

だって、やってることはiiwake"okitara"という文字列データを設定したり、この文字列に他の文字列を追加したりする程度です。

大したことないような気もしますし、ちょっとややこしいところもあるので、すごく便利か?と聞かれるとそうでもないような気もしますよね。


でも、C++言語でStringクラスと同じようなことをすると、ものすごーーーーーく大変なんです!(本当に泣きたくなるぐらい大変です!)

例えば、先ほどの例では文字列に文字列を追加しましたが、C++言語でこれだけのことをするだけで、かなりの知識が必要になって、本当に大変なんです。

ということで、Stringクラスはちょっと分かりづらいところがあるかもしれませんが、C++言語よりはマシと思って習得していただければと思います。


それでは、次にStringクラスの主要なメソッドを説明します。

Stringクラスの主要メソッド

Stringクラスには多くのメソッドがありますが、以下に主要メソッドをご紹介します。

説明内でのインスタンス名はmojiとしています。

concat

書き方

moji.concat(追加文字列);

意味

mojiの文字列に、引数の「追加文字列」を追加(後ろから連結)します。

スケッチ例

String moji("ABC");    // mojiは"ABC"
moji.concat("DEF");    // mojiに"DEF"を追加
Serial.println(moji);

結果

ABCDEF

equals

書き方

moji.equals(比較文字列);

意味

mojiの文字列が、引数の「比較文字列」と一致していればtrue、一致していなければfalseを返します。

スケッチ例

String moji("ABC");  // mojiは"ABC"

// mojiを"ABC"と一致しているかチェック
if( moji.equals("ABC") ) {
  Serial.println("一致");
} else {
  Serial.println("不一致");
}

結果

一致

compareTo

書き方

moji.compareTo(比較文字列);

意味

mojiの文字列を、引数の「比較文字列」と比較して、辞書の順番で「比較文字列」が前に来る場合は1、後ろに来る場合は-1、一致している場合は0を返します。

スケッチ例

String moji("ABC");  // mojiは"ABC"

Serial.println( moji.compareTo("AAA");  // "ABC"と"AAA"の辞書順比較
Serial.println( moji.compareTo("ABD");  // "ABC"と"ABD"の辞書順比較

結果

1
-1

length

書き方

moji.length();

意味

mojiの文字列の長さを返します。引数はありません。

スケッチ例

String moji("ABCDEFG");  // mojiは"ABCDEFG"

Serial.println( moji.length() );  // mojiの長さをシリアルモニタに表示

結果

7

replace

書き方

moji.replace(検索文字列, 置き換え文字列);

意味

mojiの文字列を調べて、「検索文字列」の部分を「置き換え文字列」に置き換えます。

スケッチ例

String moji("ABCD");  // mojiは"ABCD"

Serial.println( moji.replace("AB", "ab") );  // mojiの中の"AB"を"ab"に置き換え

結果

abCD

substring

書き方

moji.substring(開始位置, 終了位置);

意味

mojiの文字列の、「開始位置」文字目から「終了位置」文字目までの文字列を返します。

文字列の位置は先頭を0として数えます。

「終了位置」が省略された場合は「開始位置」文字目から最後までの文字列を返します。

スケッチ例

String moji("ABCDEFG");  // mojiは"ABCDEFG"

Serial.println( moji.substring(0, 2) );  // 0文字目から2文字目までを表示
Serial.println( moji.substring(3) );     // 3文字目から最後までを表示

結果

ABC
DEFG

trim

書き方

moji.trim();

意味

mojiの文字列の先頭と末尾のスペースを削除します。複数連続している場合も全て削除します。

スケッチ例

String moji("   ABC      ");  // mojiの先頭と末尾にスペースがたくさんある

Serial.println( moji.trim() );  // 先頭と末尾のスペースを削除

結果

ABC

Stringクラスの主要メソッドは以上になります。

言い訳キーボードに限らず、Arduinoの電子工作で何か文字を表示する機会は多くあると思いますので、ぜひStringクラスを活用してみてください!

次回の記事ではStringクラスを使って言い訳キーボードのスケッチを見やすくします。

更新履歴

日付内容
2021.12.18新規投稿
2025.2.18説明内容一部変更
通知の設定
通知タイミング
guest
0 コメント
新しい準
古い順 一番投票が多い
本文中にフィードバック
全てのコメントを見る
目次