数値を出力する際に出力幅を固定し、右詰めにしたり、数値のけた数が出力幅よりも少ない場合に「0」埋めしたりする方法を解説する(C# 6.0/VB 14対応)。
本稿は2004/01/30に初版公開、2008/07/10に改訂された記事を再改訂し、C# 6.0/Visual Basic 14(以下、VB 14)の補完文字列についての記述を追加したものです。また、本稿のコードは全てC# 6.0/VB 14で動作を確認しました。
数値をファイルや帳票に出力する際には、文字列の幅を固定し右詰めにしたり、0埋めで出力したりしたい場合がある。このような用途には、Stringクラス(System名前空間)のFormatメソッドを使うのが簡単だ。
Formatメソッドでは、書式を指定する「書式指定文字列」と、それに対応するオブジェクトを引数で指定する。本稿では、よく用いられるであろう整数値の文字列化に絞って解説する。
また、C# 6.0/VB 14では、「補間文字列」(interpolated string)という機能を使うことで、StringクラスのFormatメソッドを使うことなく、同じ内容のコードをより簡潔に記述できるようになっている。補間文字列を使用したコードを知りたい方はこちらを参照してほしい。
数値の書式指定を解説する前に、Formatメソッドの基本的な用法について触れておく。Formatメソッドがよく用いられるのは、次のように文字列中に変数の値を埋め込む場合だ。
string name = "鈴木";
int month = 1;
int day = 30;
string str = String.Format(
"{0}さん、今日は{1}月{2}日です", name, month, day);
// 変数strの内容:鈴木さん、今日は1月30日です
Dim name As String = "鈴木"
Dim month As Integer = 1
Dim day As Integer = 30
Dim str As String = String.Format( _
"{0}さん、今日は{1}月{2}日です", name, month, day)
' 変数strの内容:鈴木さん、今日は1月30日です
ここで、Formatメソッドの第1引数に指定した文字列が書式指定文字列であり、これには通常の文字列中に{0}や{1}などの「書式指定項目」が挿入されている。
書式指定項目とは、0から始まるインデックス番号を中カッコで囲んで記述したものだ。書式指定項目部分は、インデックス番号に対応した、第2引数以降のオブジェクトを文字列化*したもので置き換えられる。上記の例では、文字列strの内容は「鈴木さん、今日は1月30日です」となる。
* 全てのオブジェクトは、そのToStringメソッドを呼び出すことにより文字列化できる。
数値を書式指定して文字列にする場合は、書式指定項目にいくつかのパラメーターを追加して記述できる。次の表は、よく使用される四つの場合について、書式指定項目の記述例をまとめたものだ。
指定する書式 | 書式指定項目の記述例 | 出力例 |
---|---|---|
幅指定で右詰め | String.Format("{0, 4}", num) | “ 1” |
幅指定で左詰め | String.Format("{0, -4}", num) | “1 ” |
0埋め | String.Format("{0:D4}", num) または String.Format("{0:0000}", num) |
“0001” |
幅指定かつ0埋め | String.Format("{0, 8:D4}", num) | “ 0001” |
数値の書式指定でよく使用される書式指定項目の記述例 |
この表の最初の二つの書式は、生成される文字列の幅を指定する場合である。これは、書式指定項目内のインデックス番号の後にコンマ(,)で区切って文字列の幅を整数で指定する。負の値を指定した場合には、文字列は左詰めとなる。
表中の三つ目の書式は、数値を0埋めで文字列化する場合である。これには二つの記述方法がある。
一つは、
{0:D4}
のように、インデックス番号の後にコロン(:)で区切って、10進数(Decimal)を表す書式指定子「D」と、文字列の幅を表す整数(この例では「4」)を指定する。この記述は「標準数値書式指定文字列」と呼ばれるもので、詳細についてはMSDNの「標準の数値書式指定文字列」の項を参照していただきたい。ちなみに、「D」の代わりに「X」を指定すると、16進数文字列に変換される(小文字の「x」の場合は16進数文字列も小文字となる)。
0埋めの場合のもう一つの記述例である、
{0:0000}
は、インデックス番号の後にコロン(:)で区切って「ゼロプレースホルダー」と呼ばれる書式指定文字「0」を文字列の幅の数だけ並べて記述する方法だ。こちらについての詳細は、MSDNの「カスタム数値書式指定文字列」を参照していただきたい。
表中の最後の書式は、文字列の幅の指定し、かつ0埋めで文字列化する場合の記述である。書式指定項目の正式な構文は、
{インデックス番号, 文字列の幅:書式指定子}
であるが、「文字列の幅」と「書式指定子」は省略可能である。また、このような形式での書式指定の方法のことを「複合書式指定」という。
次に、Formatメソッドを利用したサンプルプログラムを示しておく。
// formatint.cs
using System;
public class FormatInteger {
static void Main() {
string output;
int zero = 0;
int eleven = 11;
//// 例1
output = String.Format("4けた右詰め【{0, 4}】", zero);
Console.WriteLine(output);
// 出力:4けた右詰め【 0】
output = String.Format("4けた右詰め【{0, 4}】", eleven);
Console.WriteLine(output);
// 出力:4けた右詰め【 11】
//// 例2
Console.WriteLine ("【{0, 4}】【{1, 4}】", zero, eleven);
// 出力:【 0】【 11】
//// 例3
Console.WriteLine("4けた左詰め【{0, -4}】", zero);
// 出力:4けた左詰め【0 】
Console.WriteLine("4けた左詰め【{0, -4}】", eleven);
// 出力:4けた左詰め【11 】
Console.WriteLine("4けた0埋め【{0:D4}】", zero);
// 出力:4けた0埋め【0000】
Console.WriteLine("4けた0埋め【{0:D4}】", eleven);
// 出力:4けた0埋め【0011】
Console.WriteLine("4けた0埋め【{0:0000}】", zero);
// 出力:4けた0埋め【0000】
Console.WriteLine("4けた0埋め【{0:0000}】", eleven);
// 出力:4けた0埋め【0011】
Console.WriteLine("8けたかつ4けた0埋め【{0, 8:D4}】", zero);
// 出力:8けたかつ4けた0埋め【 0000】
Console.WriteLine("8けたかつ4けた0埋め【{0, 8:D4}】", eleven);
// 出力:8けたかつ4けた0埋め【 0011】
//// 例4
Console.WriteLine(
"【{0, 4}】【{0, -4}】【{0:D4}】【{0:0000}】", eleven);
// 出力:【 11】【11 】【0011】【0011】
}
}
// コンパイル方法:csc formatint.cs
' formatint.vb
Imports System
Public Class FormatInteger
Shared Sub Main()
Dim output As String
Dim zero As Integer = 0
Dim eleven As Integer = 11
'''' 例1
output = String.Format("4けた右詰め【{0, 4}】", zero)
Console.WriteLine(output)
' 出力:4けた右詰め【 0】
output = String.Format("4けた右詰め【{0, 4}】", eleven)
Console.WriteLine(output)
' 出力:4けた右詰め【 11】
'''' 例2
Console.WriteLine ("【{0, 4}】【{1, 4}】", zero, eleven)
' 出力:【 0】【 11】
'''' 例3
Console.WriteLine("4けた左詰め【{0, -4}】", zero)
' 出力:4けた左詰め【0 】
Console.WriteLine("4けた左詰め【{0, -4}】", eleven)
' 出力:4けた左詰め【11 】
Console.WriteLine("4けた0埋め【{0:D4}】", zero)
' 出力:4けた0埋め【0000】
Console.WriteLine("4けた0埋め【{0:D4}】", eleven)
' 出力:4けた0埋め【0011】
Console.WriteLine("4けた0埋め【{0:0000}】", zero)
' 出力:4けた0埋め【0000】
Console.WriteLine("4けた0埋め【{0:0000}】", eleven)
' 出力:4けた0埋め【0011】
Console.WriteLine("8けたかつ4けた0埋め【{0, 8:D4}】", zero)
' 出力:8けたかつ4けた0埋め【 0000】
Console.WriteLine("8けたかつ4けた0埋め【{0, 8:D4}】", eleven)
' 出力:8けたかつ4けた0埋め【 0011】
'''' 例4
Console.WriteLine( _
"【{0, 4}】【{0, -4}】【{0:D4}】【{0:0000}】", eleven)
' 出力:【 11】【11 】【0011】【0011】
End Sub
End Class
' コンパイル方法:vbc formatint.vb
プログラム中の「例2」で示しているように、生成された文字列をコンソールに出力する場合には、Consoleクラス(System名前空間)のWriteLineメソッドでも書式指定文字列を利用できる。
また、「例4」で示しているように、書式指定文字列には同じインデックス番号を持つ書式指定項目を複数個記述することもできる。
ここまでは、StringクラスのFormatメソッドを使用して、文字列内に数値を埋め込んでいた(複合書式指定)。C# 6.0/VB 14では「補間文字列」を使用することで、文字列内への数値の埋め込みをより簡潔に行える。
補間文字列は複合書式指定におけるインデックス(「{0}」「{1}」における「0」「1」など)の部分に直接、変数や式などを記述するものだと考えると分かりやすい。また、文字列の先頭には「$」記号を付加する。簡単な例を挙げると「$"Hello {msg}"」のようになる。この場合は、変数msgの内容が文字列に埋め込まれるわけだ。
以下に補間文字列の書式を示す。
$"字面通りに表示されるテキスト { 補間式, 文字列の幅:書式指定子} ……"
「, 文字列の幅」と「:書式指定子」には上の「数値の書式指定」で説明した要領で文字列の幅や0埋めの指定を記述できる。
先ほども見たが、まずは複合書式指定を使用したコード例を見てみよう(上のコードを抜粋して再掲)。
string name = "鈴木";
int month = 1;
int day = 30;
string str = String.Format(
"{0}さん、今日は{1}月{2}日です", name, month, day);
int zero = 0;
Console.WriteLine("4けた左詰め【{0, -4}】", zero);
Dim name As String = "鈴木"
Dim month As Integer = 1
Dim day As Integer = 30
Dim str As String = String.Format( _
"{0}さん、今日は{1}月{2}日です", name, month, day)
Dim zero As Integer = 0
Console.WriteLine("4けた左詰め【{0, -4}】", zero)
補間文字列を使用すると、上のコードは次のように書き換えられる。
string name = "鈴木";
int month = 1;
int day = 30;
string str = $"{name}さん、今日は{month}月{day}日です";
int zero = 0;
Console.WriteLine($"4けた左詰め【{zero, -4}】");
Dim name As String = "鈴木"
Dim month As Integer = 1
Dim day As Integer = 30
Dim str As String = $"{name}さん、今日は{month}月{day}日です"
Dim zero As Integer = 0
Console.WriteLine($"4けた左詰め【{zero, -4}】")
String.Formatメソッド呼び出しが不要になり、また文字列中のどの位置にどの変数(や式)の値が埋め込まれるかが一目瞭然となるので、分かりやすいコードとなるはずだ。C# 6.0やVB 14で開発を行う場合には、こちらの記述方法をぜひ活用したい。なお、.NET Framework 4.6では補間文字列を使用してIFormattbale型あるいはFormattableString型のオブジェクトを作成することも可能だが、これについてはMSDNの「補間文字列 (C# および Visual Basic リファレンス)」を参照されたい。
参考までに上記のformatint.csファイルとformatint.vbファイルを、補間文字列を使用して書き直したものを以下に示す。
// interpolatedstring.cs
using System;
public class FormatInteger {
static void Main() {
string output;
int zero = 0;
int eleven = 11;
//// 例1
output = $"4けた右詰め【{zero, 4}】";
Console.WriteLine(output);
// 出力:4けた右詰め【 0】
output = $"4けた右詰め【{eleven, 4}】";
Console.WriteLine(output);
// 出力:4けた右詰め【 11】
//// 例2
Console.WriteLine ($"【{zero, 4}】【{eleven, 4}】");
// 出力:【 0】【 11】
//// 例3
Console.WriteLine($"4けた左詰め【{zero, -4}】");
// 出力:4けた左詰め【0 】
Console.WriteLine($"4けた左詰め【{eleven, -4}】");
// 出力:4けた左詰め【11 】
Console.WriteLine($"4けた0埋め【{zero:D4}】");
// 出力:4けた0埋め【0000】
Console.WriteLine($"4けた0埋め【{eleven:D4}】");
// 出力:4けた0埋め【0011】
Console.WriteLine($"4けた0埋め【{zero:0000}】");
// 出力:4けた0埋め【0000】
Console.WriteLine($"4けた0埋め【{eleven:0000}】");
// 出力:4けた0埋め【0011】
Console.WriteLine($"8けたかつ4けた0埋め【{zero, 8:D4}】");
// 出力:8けたかつ4けた0埋め【 0000】
Console.WriteLine($"8けたかつ4けた0埋め【{eleven, 8:D4}】");
// 出力:8けたかつ4けた0埋め【 0011】
//// 例4
Console.WriteLine(
$"【{eleven, 4}】【{eleven, -4}】【{eleven:D4}】【{eleven:0000}】");
// 出力:【 11】【11 】【0011】【0011】
}
}
// コンパイル方法:csc interpolatedstring.cs
' interpolatedstring.vb
Imports System
Public Class FormatInteger
Shared Sub Main()
Dim output As String
Dim zero As Integer = 0
Dim eleven As Integer = 11
'''' 例1
output = $"4けた右詰め【{zero, 4}】"
Console.WriteLine(output)
' 出力:4けた右詰め【 0】
output = $"4けた右詰め【{eleven, 4}】"
Console.WriteLine(output)
' 出力:4けた右詰め【 11】
'''' 例2
Console.WriteLine ($"【{zero, 4}】【{eleven, 4}】")
' 出力:【 0】【 11】
'''' 例3
Console.WriteLine($"4けた左詰め【{zero, -4}】")
' 出力:4けた左詰め【0 】
Console.WriteLine($"4けた左詰め【{eleven, -4}】")
' 出力:4けた左詰め【11 】
Console.WriteLine($"4けた0埋め【{zero:D4}】")
' 出力:4けた0埋め【0000】
Console.WriteLine($"4けた0埋め【{eleven:D4}】")
' 出力:4けた0埋め【0011】
Console.WriteLine($"4けた0埋め【{zero:0000}】")
' 出力:4けた0埋め【0000】
Console.WriteLine($"4けた0埋め【{eleven:0000}】")
' 出力:4けた0埋め【0011】
Console.WriteLine($"8けたかつ4けた0埋め【{zero, 8:D4}】")
' 出力:8けたかつ4けた0埋め【 0000】
Console.WriteLine($"8けたかつ4けた0埋め【{eleven, 8:D4}】")
' 出力:8けたかつ4けた0埋め【 0011】
'''' 例4
Console.WriteLine( _
$"【{eleven, 4}】【{eleven, -4}】【{eleven:D4}】【{eleven:0000}】")
' 出力:【 11】【11 】【0011】【0011】
End Sub
End Class
' コンパイル方法:vbc interpolatedstring.vb
カテゴリ:クラス・ライブラリ 処理対象:文字列
使用ライブラリ:Stringクラス(System名前空間)
使用ライブラリ:Consoleクラス(System名前空間)
■更新履歴
【2015/10/27】C# 6.0/VB(Visual Basic) 14の補間文字列に対応した記述を追加しました。
【2008/07/10】VBのコード例とサンプルプログラムを追加しました。
【2004/01/30】初版公開。
Copyright© Digital Advantage Corp. All Rights Reserved.