【ゲーム開発のためのC#入門講座・おまけ編】文字列の色んな作り方を試してみよう【#2】

9.0_C#おまけ編

ありがちな文字列連結

例えば、配列に格納されているデータをインデックスと一緒に表示するとしましょう。

表示形式は「ゲーム開発ツール[インデックス + 1]番目:[ツール名]」とします。

string[] tools = {
    "Unity",
    "UnrealEngine",
    "RPGツクール"
};
​
for (int i = 0; i < tools.Length; i++)
{
    Console.WriteLine("ゲーム開発ツール" + (i + 1).ToString() + "番目:" + tools[i]);
}
コンソール画面

ゲーム開発ツール1番目:Unity
ゲーム開発ツール2番目:UnrealEngine
ゲーム開発ツール3番目:RPGツクール

このように、複数の文字列を連結しようとすると、それぞれの文字列をひたすら「+」演算子で繋いでいく必要があります。

連結する文字列が増えれば増えるほど、どんどん読み辛くなっていきます……。

// ↓いっぱい連結されるとすごく読み辛い!
string text = "hoge" + i + "fuga" + j + "hogefuga" + k + index.ToString() + "!!";

そこで、C#にはもっと読みやすく文字列を連結して作成する方法が用意されています。

それが「文字列補間」です。

文字列補完で文字列を連結しよう

文字列補完は変数や計算結果を直接文字列内に記述することができる機能です。

早速実例を見てみましょう。

string[] tools = {
    "Unity",
    "UnrealEngine",
    "RPGツクール"
};
​
for (int i = 0; i < tools.Length; i++)
{
    // Console.WriteLine("ゲーム開発ツール" + (i + 1).ToString() + "番目:" + tools[i]);
    Console.WriteLine($"ゲーム開発ツール{i + 1}番目:{tools[i]}");
}
コンソール画面

ゲーム開発ツール1番目:Unity
ゲーム開発ツール2番目:UnrealEngine
ゲーム開発ツール3番目:RPGツクール

元の文字列をコメントで記述しています。

どうでしょうか。元の記述方法よりもだいぶすっきりして見えますよね。また、1ペアのダブルクオーテーション内にすべての記述がまとまっているので、定義内容も理解しやすいです(ここは個人差あるかもしれません)。

文字列補完の構文は下記の通り。

$"文字列{変数}文字列";

ルールとしては、

  1. 先頭に必ず「$」をつける
  2. 変数や処理を記述する際は{}で囲む

となります。

この方法を使えば、先程例として提示した大量連結もすっきり書くことができます。

// string text = "hoge" + i + "fuga" + j + "hogefuga" + k + index.ToString() + "!!";
string text = $"hoge{i}fuga{j}hogefuga{k}{index}!!";

便利ですね!

以前のC#ではstring型のstaticメソッド「Format」が同様の機能を持っていました。

string[] tools = {
    "Unity",
    "UnrealEngine",
    "RPGツクール"
};
​
for (int i = 0; i < tools.Length; i++)
{
    string text = string.Format("ゲーム開発ツール{0}番目:{1}",
                                i + 1, //{0}にあてはめるもの
                                tools[i]); // {1}にあてはめるもの
    Console.WriteLine(text);
}

「{}」で囲まれた部分に、その番号の通りに後続引数を設定するというものです。

これはこれで文字列を「+」演算子で記述するよりはすっきりして見えるのですが、番号の指定間違いや引数が多い場合の可読性など、まだまだ難点がありました。

そこでC#6.0から文字列補完機能が導入されたという経緯があるため、皆さんは積極的に新しい技術「文字列補完」の方を使っていくとよいでしょう。

ToStringの書式で変換方法を指定しよう

続いて、今度は異なる型を文字列に変換してくれるメソッド「ToString」です。

これまで「ToString」は引数なしでしか使ってきませんでした。

が、実は「ToString」メソッドには引数あり版のオーバーロードメソッドがあります。

これがとにかく便利で活用する機会も多いのですが、特に便利な使い方として、代表的な例をご紹介しましょう。

日付や時刻の文字列化と書式

日付や時刻を「ToString」メソッドで文字列化してみましょう。

Console.WriteLine(DateTime.Now.ToString());
コンソール画面

2022/03/08 17:51:51

DateTime型のプロパティ「Now」は今時点の日付と時刻が設定されています。

単純に引数なしで指定するとこのように「西暦年/月/日 時:分:秒」で出力されます。

ですが、「/」ではなく「-」で連結して出力したいとか、時刻はいらないから日付だけ出力したいとか、月と日は1桁なら0はつけたくないとか、単純に日付を文字列にするといっても様々なニーズがある訳です。

この変換方法を定義・指定することができるのが、「ToString」メソッドの引数で、一般的に書式と言われる文字列です。

早速色んな変換方法を確認してみましょう。

Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd"));
Console.WriteLine(DateTime.Now.ToString("yyyy/M/d"));
Console.WriteLine(DateTime.Now.ToString("HH時mm分ss秒"));
コンソール画面

2022-03-08
2022/3/8
17時58分40秒

同じ変数に対する「ToString」メソッドですが、引数に指定した書式に従ってそれぞれ変換されていることがよくわかりますね。

日付・時刻に関する代表的な書式を確認してみましょう。

書式意味
yyyy4桁の西暦年2022
yy下2桁の西暦年22
MM月(不足桁は0埋め)03
M月(桁埋めなし)3
dd日(不足桁は0埋め)08
d日(桁埋めなし)8
HH時刻(0~24。不足桁は0埋め)09
H時刻(0~24。桁埋めなし)9
hh時刻(0~12。不足桁は0埋め)03(15時でも03)
h時刻(0~12。桁埋めなし)3(15時でも3)
mm分(0~59。不足桁は0埋め)08
m分(0~59。桁埋めなし)8
ss秒(0~59。不足桁は0埋め)07
s秒(0~59。桁埋めなし)7

代表的なと言いながら結構な数になってしまいましたね。

ただ、記述する数や大文字小文字によるバリエーションが多いので、基本的に下記の法則だけ覚えておけば問題ないでしょう。

日付の書式で
使う文字
意味覚え方
yyearの頭文字
Mmonthの頭文字(minuteと被っているので大文字小文字に注意)
ddayの頭文字
Hhourの頭文字
mminuteの頭文字(monthと被っているので大文字小文字に注意)
ssecondの頭文字

すべて英語の頭文字なので、法則さえ理解しておけば、覚えるのは難しくなさそうですね。

列挙型の文字列化と書式

列挙型の「ToString」メソッドは、引数なしの場合、定義された名称が出力されます。

Console.WriteLine(Rank.First.ToString());

enum Rank
{
    First = 1,
    Second,
    Third
};
コンソール画面

First

ただ、名称ではなく数値を出力したり別の文字列と連結したい場面もままあります。

そういった場合は「ToString」メソッドの引数に「d」または「D」を設定すると、名称ではなく数値の方が文字列化されるようになります。

Console.WriteLine(Rank.First.ToString("d"));

enum Rank
{
    First = 1,
    Second,
    Third
};
コンソール画面

1

小数を扱える数値型の文字列化と書式

float型やdouble型といった小数点以下の数値を扱える型では、引数として渡す書式によって、出力する小数桁数をコントロールすることができます。

double number = 12.345678901;
Console.WriteLine(number.ToString());
Console.WriteLine(number.ToString("0.00"));
Console.WriteLine(number.ToString("0.0000"));
コンソール画面

12.345678901
12.35
12.3457

他にも、金額形式で出力してくれる書式もあったり(引数がもうひとつ必要ですが)。

using System.Globalization;
int money = 12345;
Console.WriteLine(money.ToString("C", CultureInfo.CurrentCulture));

\12,345

このように、「ToString」メソッドで用いられる書式はとにかく種類が豊富で奥が深いものとなっています。全部覚えるのはよっぽど記憶力の良い人でないと無理なので、その都度、自分が実現したい内容を可能にする書式がないか調べながら活用していくとよいでしょう。

文字の定義方法

最後におまけで、文字列ではなく文字の定義方法をご紹介します。

C#では文字はchar型、そしてその文字の集合体である文字列はstring型と、文字と文字列が明確に区別されています。

この1文字を表すchar型はstring型ではないので「"(ダブルクオーテーション)」では囲みません。代わりに「’(シングルクオーテーション)」で囲みます。

char data = 'A';
Console.WriteLine(data);

あまりこのchar型を使う機会はないかと思いますが、たまに必要になる場面もあるので、頭の片隅にでも覚えておくとよいでしょう。

まとめ

  • 文字列補完は変数や計算結果を直接文字列内に記述することができる機能。一組のダブルクオーテーション内で定義を完結させることができるので、すっきり見やすく文字列を結合できる
  • 「ToString」メソッドのオーバーロードメソッドにて書式を指定すると、文字列への変換方法を様々に指定することができる。とにかく種類が豊富でとても覚えきれるものではないので、その都度、自分が実現したい内容を可能にする書式がないか調べながら活用していこう
  • C#では文字と文字列は別物。だから文字であるchar型は「"(ダブルクオーテーション)」ではなく「’(シングルクオーテーション)」で囲む

Unityでも文字列を使う機会は多いので、ここで学んだことがきっと役立つことでしょう。ぜひマスターして便利に活用してみてください。

それでは、今回もお疲れ様でした!

また次の記事でお会いしましょう!

Posted by yuumekou