C言語のプログラムでsetlocaleの使い方がわかりません。


以前はUNIX環境で日本語を正しく表示するには次のことをしなければならなりませんでした。

- 環境変数LANGやLC_ALLなどの設定
- ターミナルソフトの言語設定

今となってはUTF8一択のような感じですが、この時代SJISで作ったプログラムをロケールがEUCのシェルで正しく表示するようなやり方があったのでしょうか?
結局、iconvなどを利用して文字コード変換をする必要があったのでしょうか。

私が調べた限りでは次の通りでした。

- setlocaleは通貨や、時間表記に非常に影響を与える。
- POSIXの定義( http://pubs.opengroup.org/onlinepubs/007908799/xbd/envvar.html )によるとisalphaなどの関数がsetlocaleの影響を受ける。
- → printfなども影響を受けるが、単なるバイトの列である文字コードの変換は行ってくれなさそう・・・(実験済み)
- 文字列を直でprintfしてもダメだが、メッセージカタログや、gettextなどには影響がありそう
- ELFなどの実行バイナリフォーマット文字列に関する文字コード情報はない

わかりづらい場合はその旨コメントで書き込んでいただければと思います。直していきたいと思います。

回答の条件
  • 1人1回まで
  • 登録:
  • 終了:2017/04/10 06:05:05
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:a-kuma3 No.1

回答回数4973ベストアンサー獲得回数2154

ポイント200pt

setlocale は、国際化(i18n:internationalization)の仕組みのうちのひとつです。

いろいろな国の言語に対応しようと思うと、文字コード(charset)だけではなく、

  • 語句の出現順序
  • 区切り文字

なんかも違ってくるので、そこらあたりを楽にしようという仕組みです。

日本語の文字コードが SJIS だ EUC だ、というのは、その仕組みに乗っかって一部だけを利用しています(五区の出現順序や区切り文字は、日本語という範疇で同じなので)。

質問に挙げられた pubs.opengroup.org であれば、以下のようなページの方が本質に近いです。

man なら、セクションが 5 とか 7 とか。
https://linuxjm.osdn.jp/html/LDP_man-pages/man7/locale.7.html

i18n の目指すところは、

  • 言語による差異を、プログラムではなく、外部のファイルに逃がすことができる
  • ある言語に対応するときに、プログラムを変更せずとも、外部のファイルを追加することで対応できる

です。

setlocale 関数だけに絞って言うと、問い合わせ(第2引数が NULL)以外では使った記憶がありません。
言語によって、文字数が変わるので、切り替えたりするとか。


日本語の文字コードの範囲に絞ると、入力 or 出力の文字コードだけの話になるので、

この時代SJISで作ったプログラムをロケールがEUCのシェルで正しく表示するようなやり方があったのでしょうか?

については、入力 or 出力を iconv のようなコマンドで変換するという方法を使いました。

「この時代SJISで作ったプログラム」というのが、i18n にのっとったプログラムであれば、EUC に対応してないプログラムでも EUC の外部ファイルを用意すれば文字化けせずに動作しますが、i18n にのっとっているプログラムであれば「SJIS で作ったプログラム」という表現はされないと思うので、文字コードを変換するコマンドを間に挟むしかありません。

id:pepc

早速のご回答ありがとうございます。

setlocale は、国際化(i18n:internationalization)の仕組みのうちのひとつです。


i18n の目指すところは、
- 言語による差異を、プログラムではなく、外部のファイルに逃がすことができる
- ある言語に対応するときに、プログラムを変更せずとも、外部のファイルを追加することで対応できる
です。


は目から鱗でした。
setlocaleというか、i18nは基本は外部ファイル化(gettextやcatgetsとか)することが大切なのですね。
外部化した上で、SJISやEUCのファイルを用意するのが正解ということですね。
なんとなくの知識としてはありましたが、こちらまでリンクできておらず、理解が深まった気がします。

外部化するほどでもないプログラムについてはiconvなどでコマンドで変換してやるのが一般的という感じなのですね。

i18nをキーワードにすると下記のようなページが見られ、さらに理解が深まった気がします(catgetsが多めですが・・・)。
- https://h50146.www5.hpe.com/products/servers/nonstop/download/pdfs/intro/116809J.pdf
- http://euc.jp/i18n/msgcat.ja.html
- http://www1.kokusaika.jp/advisory/org/ja/c_preface.html

ありがとうございました。

2017/04/05 07:02:53

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません