1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Posted at

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 推奨ということでそちらに倒してます。でないと乱れる。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?