Help us understand the problem. What is going on with this article?

Kinx Tips - UTF8 文字列のフォーマッティング

Kinx Tips - UTF8 文字列のフォーマッティング

はじめに

「見た目は JavaScript、頭脳(中身)は Ruby、(安定感は AC/DC)」 でお届けしているスクリプト言語 Kinx。Kinx で実装したちょっとした小技を紹介。

そう、ちょっとした小技。

UTF8 文字列のフォーマッティングの問題

C 言語の printf

UTF8 はバイト数と文字幅が一致しないので、"%-20s" とかしても微妙に揃いませんよね。半角カナも試しに使ってみましょう。

#include <stdio.h>

int main()
{
    struct fruits {
        char *name;
        int price;
    } fruits[] = {
        { .name = "りんご", .price = 230 },
        { .name = "みかん(1袋)", .price = 450 },
        { .name = "グレープフルーツ", .price = 120 },
    };
    printf("01234567890123456789\n");
    for (int i = 0; i < sizeof(fruits)/sizeof(fruits[0]); ++i) {
        printf("%-20s ... %3d 円\n", fruits[i].name, fruits[i].price);
    }
    return 0;
}

結果はこうなります。

01234567890123456789
りんご            ... 230 円
みかん(1袋)      ... 450 円
グレープフルーツ ... 120 円

基本的にバイト数なので、日本語 3 バイトであれば 3 消費します。したがって幅が縮みます。

Ruby の sprintf

C と同じかと思いきや、違います。

fruits = [
    ["りんご", 230],
    ["みかん(1袋)", 450],
    ["グレープフルーツ", 120],
]

puts "01234567890123456789"
fruits.each {|name, price|
    puts sprintf("%-20s ... %3d 円", name, price)
}

結果はこうなりました。

01234567890123456789
りんご                  ... 230 円
みかん(1袋)              ... 450 円
グレープフルーツ           ... 120 円

バイト数ではなく文字数です。日本語も(何バイトであろうと) 1 文字で 1 消費します。なので、表示幅が増えます。文字数なので、半角カナだと実は一致します。

Kinx のフォーマッタ

Kinx では UTF8 の文字幅を確認してフォーマット文字列の数値部分を自動調整します。表示幅として機能します。

var fruits = [
    ["りんご", 230],
    ["みかん(1袋)", 450],
    ["グレープフルーツ", 120],
];

System.println("01234567890123456789");
fruits.each(&(e) => {
    System.println("%-20s ... %3d 円" % e[0] % e[1]);
});

結果はこうなります。

01234567890123456789
りんご               ... 230 円
みかん(1袋)          ... 450 円
グレープフルーツ           ... 120 円

Qiita のコードブロックでは等幅で表示されていない感じなので微妙ですが、等幅フォントで見れば縦ラインはきちんと揃っています。東アジア文字幅(East Asian Width)に従って調整するので概ねうまく動くはず 1

多くの人が期待する動作は コレ ではないでしょうか。

おわりに

なかなか忙しくて記事が書けないとき用に、こういった小ネタもストックしておこう。

ではまた、次回。


  1. ここ」に従うと、東アジアの従来文字コードの文脈では Ambiguous Unicode characters は fullwidth 推奨ということでそちらに倒してます。でないと乱れる。 

Kray-G
C++ & boost lover だったが、禅の心持ちというかシンプル・イズ・ザ・ベストの精神で C に回帰中。メタルからロックンロールに戻ってきて Rolling Stones に今更夢中。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした