質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Q&A

解決済

2回答

9334閲覧

Atomエディタ "〜"の扱い

ji6othin

総合スコア11

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

0グッド

1クリップ

投稿2017/01/28 17:38

編集2017/01/28 17:40

・環境
Windows10
Atom(2017/01/28時点最新ver)
開発言語:php,JavaScript

・現象
Atomエディタで"〜"と書いた箇所が、
他のエディタで見ると文字化け(他の文字になる)する。

Atom → "〜"を書いて保存
秀丸で開く → "・"で表示
No editorで開く → 文字化け

逆に、
秀丸(No editor) → "〜"を書いて保存
No editor(秀丸)で開く → "〜"で表示
Atom → 文字化け

文字コード設定は全てEUC-jpになっています。
環境依存文字(①やその他特殊記号等)は性格に表示されます。

色々調べたのですが、これといった
解決策が見つからず困惑しております。

これはAtom側の仕様?バグ?なのでしょうか。
ご回答のほどよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

まず前提知識として、次のことを知っておいてください。

  • Atom(というよりJavaScript)は文字列を全てUnicode(正確にはUTF-16)で扱っており、文字コードの選択に関わらず、エディタ上では全てUnicodeで処理している。指定の文字コードへのデコード/エンコードはファイルの読み書き時に発生する。
  • Unicodeには全角幅のチルダがU+301CとU+FF5Eの二つ存在する。(Unicode 8.0からはこの二つの文字は同じグリフになったため、同じ文字のように表示されますが、実際のコードポイントは異なります。)

Atomで書き込み時のエンコードをどこで行っているかは下記のようになっています。

  1. エディタで表示編集するファイルに対する操作はAtomのコアから切り離されて、text-bufferパッケージで行っている。
  2. text-bufferではpathwatcherのFileを使用している。
  3. pathwatechrのFileではUTF-8__以外__でエンコードする場合はiconv-liteを使ってエンコードしてからファイルを書き込んでいる。(UnicodeからUTF-8への変換はNode.jsに組み込まれているため、Node.jsをそのまま使用)

ファイルの読み込みも同様にiconv-liteでデコードしています。

iconv-liteが変換に使っているのがマップ表であるeucjp.jsonです。この中ではU+FF5E"a1c1""8fa2b7"二つに割り当てられていますが、U+301C割り当てられていません。このため、読み込みでは

  • A1 C1 => U+FF5E
  • 8F A2 B7 => U+FF5E

となりますが、書き込みでは

  • U+301C => 3F ※ 割り当て無しのため?に変換
  • U+FF5E => 8F A2 B7 ※ A1 C1 より後のためか、エンコードはこちらが優先される。

となります。

その他、Shfit_JISおよびその亜種のCP932についてまとめると下記のようになっています。

|Unicode|名称|文字|UTF-8|JIS X 0213|EUC-JP|Shfit_JIS|CP932|
|---|---|---|---|---|---|---|
|U+301C|WAVE DASH||E3 80 9C|1-1-33|3F(?)|3F(?)|3F(?)|
|U+FF5E|FULLWIDTH TILDA||EF BD 9E|1-2-18|8F A2 B7|81 60|81 60|

※ JIS X 0213の1-2-18には通常のチルダU+007E~も割り当てられています。
※ EUC-JPは A1 C1 も読み込め、同じ 8F A2 B7 と同じU+FF5Eに変換されます。
※ 3F はASCIIの?であり、割り当て無しのための代替文字として使われています。

8F A2 B7 は何かというとJIS X 0213(JIS補助漢字)での2-23です。EUC-JPとしてはある意味正しいですが、ある意味正しくありません。なぜなら、他の実装は次のようになっているからです。

  • U+301Cを A1 C1 に割り当て、U+FF5Eは何も割り当てていない。(変換もできない)
  • EUC-JPの3バイト表記(8Fや8Eから始まる)に対応していない、または、8E(半角カタカナ)のみ対応している。そのため、8F A2 B7 は変換不可で文字化け等が起きる。

そのため、相互にEUC-JPとなった文字をやり取りするときに、おかしな動作を行います。

結論としては、iconv-liteの不具合と考えられます。しかし、チルダ問題は現状実装依存であり、これが正解という変換が存在しません。よって、現代的なプログラミングにおいては、全てをUTF-8で統一することが現実解と思われます。

それでもEUC-JPを使い続けたい場合はiconv-liteをforkして、マッピングのJSONを編集し、それを読み込むようにAtomをハックするしかないでしょう。

(iconv-liteにissue#145として投げました。修正されれば、そのうち直るかと思います。)

投稿2017/01/28 23:00

編集2017/01/29 07:24
raccy

総合スコア21735

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ji6othin

2017/01/29 01:42

回答ありがとうございます。 とても詳しい解説ありがとうございます。 文字コードについて、もう少し勉強してみようと思います。 ありがとうございました。
ikedas

2017/01/29 02:28

補足しておきますが、ざっと見たところ、iconv-liteのコード表はeucjp-msに相当するのではないかと思います (詳細に見ていないので独自の変更などもあるかもしれませんが)。少なくともプログラミングの用途のためには、eucjp-ascii相当に変えていただきたいところです。 詳細: http://web.archive.org/web/19990203125608/http://www.opengroup.or.jp/jvc/cde/ucs-conv.html 多くの実装では、eucjp-msかeucjp-asciiを基本に、往復変換での両者の互換性が保たれるようにしています。 ちなみに、波ダッシュと全角チルダはグリフがそっくりでもまったく別の文字ですので、コードで分離すること自体は合理性があります (ロと口のコードが違うのと同じ)。
raccy

2017/01/29 04:49

私としてはA1 C1にU+301Cを割り当てるべきところをU+FF5Eに割り当ててしまったプログラム上の不具合だと思っています。8F A2 B7にU+FF5Eを割り当てていること自体はおかしくないと思います。 変換表は、iconv-liteの名前の通りiconvを元にしていると思われます。GNU libiconvを見る限り、A1 C1はU+301Cです。また、Shift_JISの方もlibiconvにあわせてU+FF5EではなくU+301Cを使うべきです。CP932はもともとのマップ表ではU+FF5Eですが、libiconvではU+301Cを使っている(U+FF5Eにはしないとソースのコメントに書いてある)、どうするかは微妙なところです。
ikedas

2017/01/29 06:12

「ロと口」は揚げ足取りっぽかったですね。すみません。 eucjp-msはcp932との互換性を考慮したもので、公的な規格として根拠になるマッピングはありません。eucjp-ascii (JIS X 0208及びISO/IEC 646国際基準版) か、eucjp-0201 (JIS X 0208及びJIS X 0201) に準拠するのが本来だと思います (上記ページ末尾のリンク先を参照)。 何か参考になる実装ということでは、一番信頼できるのはNKFかと思います。 よろしくお願いします!
raccy

2017/01/29 07:21

とりあえず、つたない英語でissueになげました。根拠はlibiconvにしています。 https://github.com/ashtuchkin/iconv-lite/issues/145 > ikedasさん NKFを根拠にすべきであれば、上記issueで意見していただければと思います。後はコントリビューターが判断してくれると思います。
ikedas

2017/01/29 07:40

了解です。ただこのほかにもマイクロソフト独自マッピングはあるので (EM DASH、DOUBLE VERTICAL LINE、MINUS SIGN、……)、まとめます。少々時間がかかります。
guest

0

結論としては、仕様だと思います。
ややこしい文字コードの問題があります。(「波ダッシュ問題」と呼ばれることもあるようです)

Unicodeには、~という文字にも「波ダッシュ」「全角チルダ」の2つの文字があります。
(フォントによっては同じ字体で表示されます)

AtomでEUC-JPとして「~」を保存すると0x8FA2B7(全角チルダ)として保存されますが、
秀丸では0xA1C1(波ダッシュ)として保存されます。

一方、秀丸では0x8FA2B7(全角チルダ)を表示できないようです。
(ちなみに、私の環境では秀丸で保存した「~」をAtomで表示できました)

EUC-JP + Atomのまま解決するのは難しいと思います。
UTF-8 + Atomにするとか、EUC-JP + 秀丸にするとかが無難かなと思います。

投稿2017/01/28 22:58

bash_sh

総合スコア30

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ji6othin

2017/01/29 01:38

回答ありがとうございます。 どうしても現場の都合上EUC-JPで 開発しなければならないのです…。 全角チルダ、波ダッシュ問題は初めて聞きました。 少し自分でも調べてみようと思います。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問