各言語のprintfはロケールに依存するか

言語やライブラリによっては、printf系関数の出力がロケールに依存する場合があります。たとえば、ロケールによっては小数点がカンマで出力される場合があります。

手元の各環境で調べたところ、次のとおりでした。

C (POSIX.1-2008, eglibc 2.19)

POSIXが定義するprintf関数の出力はロケールに依存します。

// printf.c
#include <stdio.h>
#include <locale.h>

int main(void)
{
    setlocale(LC_ALL, "");
    printf("%g\n", 3.14);
    return 0;
}
$ gcc printf.c -o printf
$ LANG=da_DK.utf8 ./printf
3,14

Java (Java SE 8)

Javaのprintf系メソッドの出力はロケールに依存します。ロケールは引数として明示的に指定することもできます。

public class Printf {
    public static void main(String[] args) {
        System.out.printf("%g%n", 3.14);
    }
}
$ javac Printf.java
$ LANG=da_DK.utf8 java Printf
3,14000

Golang (1.7.5)

Go言語のprintf系メソッドの出力はロケールに依存しません。

package main

// #include <locale.h>
import "C"
import "fmt"

const LC_ALL = 6

func main() {
    C.setlocale(LC_ALL, C.CString(""))
    fmt.Printf("%g\n", 3.14)
}
$ LANG=da_DK.utf8 go run printf.go
3.14

Python (2.7)

Pythonの%演算子の結果はロケールに依存しません。ロケールに依存した出力を行うためにはlocale.format関数を使います。

import locale

locale.setlocale(locale.LC_ALL, '')
print "%g" % 3.14
$ LANG=da_DK.utf8 python printf.py
3.14

Ruby (1.9.3)

Rubyのprintf系関数の結果はロケールに依存しません。マニュアルに明記はされていません。

require 'dl/import'

module Libc
  extend DL::Importer
  dlload 'libc.so.6'
  extern 'char *setlocale(int, const char *)'
end

LC_ALL = 6
Libc.setlocale(LC_ALL, '')
printf("%g\n", 3.14)
$ LANG=da_DK.utf8 ruby printf.rb
3.14

Lua (5.2.3)

Luaのstring.format関数の結果はロケールに依存します。ISO Cのsnprintfに従うものとして定義されています。

os.setlocale("", "all")
print(string.format("%g", 3.14))
$ LANG=da_DK.utf8 lua printf.lua
3,14