Haskell でSJIS文字列に変換したときのバイト数を得る。

  • HaskellSJIS文字列に変換したときのバイト数を得る。

ターミナルに表を表示するときには固定幅フォントを使いますが、アルファベット、半角カナの混じった日本語を使って表を表示すると表が乱れてしまいます。
幅が半角フォントは全角フォントの半分ですから、Haskell の文字数と文字列の幅は一致しません。CStringに変換したときのバイト数が文字列の長さになります。

module Main where

import Data.Char                 (chr,ord)
import Cinnamon.Nkf              (nkf)
import Codec.Binary.UTF8.String  (encode,decode)
import Control.Applicative       ((<$>))
import Foreign.C.String          (newCStringLen)

sjisToUtf8, utf8ToSjis :: String -> String
sjisToUtf8 = nkf "-m0xSw80"
utf8ToSjis = nkf "-m0xW8s"

sjisToUcs4' :: String -> String
sjisToUcs4' = decode.map (fromIntegral.ord).sjisToUtf8

ucs4ToSjis' :: String -> String
ucs4ToSjis' = utf8ToSjis.map (chr.fromIntegral).encode

sjisByteSize :: String -> IO Int
sjisByteSize s = snd <$> newCStringLen (ucs4ToSjis' s)

main :: IO ()
main = do
  print =<< sjisByteSize "12"                -- > 2
  print =<< sjisByteSize "12全"              -- > 4
  print =<< sjisByteSize "12アイウエオ"           -- >  7
  print =<< sjisByteSize "12アイウエオハヒフヘホ"  -- > 17