書式化文字列 (format / sprintf)

C言語の sprintf のような書式で文字列を組み立てられるプログラミング言語が多いので、以下は各言語でのその方法のメモ。

文字列を組み立てるのにオブジェクトを1つずつ文字列に変換しながら+演算子などで連結していくよりは、 sprintf みたいな書式化文字列で一度にまとめて文字列に変換できると便利だよね。

書式化文字列でなくても文字列の中に変数を埋め込む書き方を使うことで、細かい書式までは指定できないが sprintf の代わりに文字列を組み立てることもできる。

C言語 snprintf(dst, sizeof(dst), "%s %d", str, i)
Go言語 fmt.Sprintf("%s %d\n", str, i)
Java String.format("%s %d", str, i)
Scala "%s %d".format(str, i)
PHP sprintf("%s %d", $str, $i)
Python "%s %d" % (str, i)
Ruby "%s %d" % [str, i]
Perl sprintf("%s %d", $str, $i)
スポンサーリンク

C言語, C++

int sprintf(char *str, const char *format, ...);
int snprintf(char *str, size_t size, const char *format, ...);

char[] dst = new char[1024];
sprintf(dst, "%s %d", str, i);

/* snprintfはバッファオーバーラン(バッファオーバーフロー)を防ぐために */
/* 文字数の限界を指定できる関数 */
snprintf(dst, sizeof(dst), "%s %d", str, i);

Go言語 (golang)

fmtパッケージのSprintf関数を使う。

package main

import "fmt"

func main() {
    var str = fmt.Sprintf("%s %d\n", "Hello", 123);
    fmt.Print(str)
    // => Hello 123
}

fmt | The Go Programming Language
https://golang.org/pkg/fmt/

Java / Scala

JavaではString.formatメソッドでC言語のsprintfと同様のことができる。 ScalaではStringOps#formatメソッドを使うこともできる。書式化文字列のフォーマットはJava/Scalaで同じ。

Javaでの例 (Javaではクラスメソッド)

String formatted = String.format("%s %d", str, i);

Scalaでの例 (ScalaのStringOps#formatはインスタンスメソッド)

val formatted = "%s %d".format(str, i);

ScalaでJavaのクラスメソッドを使うこともできるが、インスタンスメソッドのほうが短く書ける。

Signature:

String.format("%s %d", str, i)

Format String Syntax | Java Platform SE 8 Javadoc
http://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html#syntax

PHP

sprintf というC言語と同じ名前の関数がある。

$formatted = sprintf("%s %d", $str, $i);

フォーマット文字列 | PHP Manual
http://www.php.net/manual/ja/function.sprintf.php#refsect1-function.sprintf-parameters

sprintf 関数 | PHP Manual
http://www.php.net/manual/ja/function.sprintf.php

文字列生成ではなく直接標準出力する printf もある。

printf 関数 | PHP Manual
http://www.php.net/manual/ja/function.printf.php

Python

%演算子でC言語のsprintfと同様のことができる。

"%s %d" % (str, i)

引数が1つの場合はカッコを省略できる。本当はカッコを付けると複数の引数を渡せるというよりは、タプルを 1つ渡している、というイメージみたい。なので、以下のようなコードは見た目は % に1つしか値を渡していないが、中身がタプルなので、括弧で複数の引数を渡したときと同じ扱いになる。

# Python2 でも Python3 でもエラー
# TypeError: not all arguments converted during string formatting
t = ("Ichiro", "Suzuki")
"Hello, %s" % t

引数をディクショナリにして、書式文字列から名前で値を参照することもできる。

書式指定ミニ言語仕様 | Python 2.7 documentation
http://docs.python.jp/2/library/string.html#format-specification-mini-language

書式指定ミニ言語仕様 | Python 3 documentation
http://docs.python.jp/3/library/string.html#format-specification-mini-language

% 演算子以外に、formatという文字列のメソッドもある。

string.format | Python 2.7 documentation
http://docs.python.jp/2/library/stdtypes.html#str.format

string.format | Python 3 documentation
http://docs.python.jp/3/library/stdtypes.html#str.format

Ruby

sprintf関数または%演算子でC言語のsprintfと同様のことができる。

"%s %d" % [str, i]

または

sprintf("%s %d", str, i)

sprintfフォーマット | Ruby 2.1 リファレンスマニュアル
http://docs.ruby-lang.org/ja/2.1.0/doc/print_format.html

Perl

sprintf関数でC言語のsprintfと同じような書式化文字列が使える。内部でC言語のsprintfを呼び出しているわけではなくPerlで独自に実装されているらしい。

$formatted = sprintf("%s %d", $str, $i)

printf関数で標準出力やファイルへの出力もできる。

sprintf 関数 | perldoc.jp
http://perldoc.jp/func/sprintf

printf 関数 | perldoc.jp
http://perldoc.jp/func/printf

JavaScript

sprintfのようなものがない。

整数を "%04d" のようにフォーマットしたい場合は

("000" + num).substr(-4)

のようにする。ただしnumは0以上の整数であることが前提。

substr では後ろから4文字を取得するので、numが0から9999までの整数であれば、結果的に%04d"のフォーマットを取得できる。負だったり5桁以上の整数だと意図したとおりにはならない。

sprintfみたいなものを多くの人が独自に実装しているようなので、探すといいかも。

このサイトは筆者(hydrocul)の個人メモの集合です。すべてのページは永遠に未完成です。