none
CStdioFileでテキストの文字コードを認識 RRS feed

  • 質問

  • Shift-JIS/UTF-16/UTF-8などのテキストを、内部で種類を認識して、
    行単位でCStringに読み込める方法やクラスはありませんでしょうか。

    テキストやCSVのファイルを行単位でCStringに読み込むために、
    CStdioFile::ReadString()を利用しているのですが、
    最近のメモ帳は標準でUTF-8(BOMなし)で出力されてしまうので、
    この方法では読み込めないことが多くなってしまいました。

    事前に文字コードがわかっていたら、
    fopen()のモードの指定で読み込めるようにはできるようですが、
    ユーザーが作成するテキストの文字コードは想定できないものとして、
    この辺を自動で認識できないものかと思っています。

    よろしくお願いいたします。

    2020年6月10日 7:58

回答

すべての返信

  • 認識して欲しい文字コードは人によって異なるので、ほとんど無理かと。とりあえずは提供されていないと考えるべきです。

    一応、Internet Explorerと共に提供されているMLang.dllIMultiLanguage2::DetectInputCodepageが用意されているのでこれを使えば何かできるかもしれません。

    • 回答としてマーク nobuo_h 2020年6月22日 0:09
    2020年6月12日 1:10
  • 解説ありがとうございます。
    メモ帳でファイルを開く際の「文字コード:自動検出」と同じことが
    したいだけだったのですが、APIとしては用意されていないのですかね。

    IMultiLanguage2の情報もありがとうございます。
    まだちょっと使い方がわかりませんが、調べてみたいと思います。

    2020年6月15日 0:55
  • nobuo_hさん、こんにちは。フォーラムオペレーターのクモです。
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    本件、佐祐理さんより参考になる投稿が寄せられたようでなによりです。

    [回答としてマーク]機能は設定された投稿が後から参照しやすくなりますので、
    同じ問題でお困りの方のためにも参考になった投稿に設定いただけますと幸いです。

    お手数ですが、ご協力の程どうかよろしくお願いいたします。

    引き続きMSDNフォーラムをご利用いただけますようお願い申し上げます。

    MSDN/ TechNet Community Support Kumo ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、 ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~

    2020年6月15日 6:53
    モデレータ
  • 回答マークの対応が遅れて申し訳ありません。

    なお、CodeProjectなども見てみたのですが、
    事前に文字コードがわかっていたり、ちゃんとBOMが入っていたりすれば、
    正しく行単位で読み込む方法やクラスがありましたが、
    メモ帳などが出力するUTF-8(BOMなし)のテキストを判別する方法は
    見つけられませんでした。

    もちろん、今までもShift-JIS前提になっていたのはわかっていますが、
    メモ帳の標準テキストが読み込めないようになってしまったのは厳しいです。

    回答マークは付けさせていただきますが、
    他の方はこのような最近のテキストファイルをどうやって読み込んでいるのか、
    体験談があれば引き続き教えていただければと思います。

    2020年6月22日 0:11
  • 「認識して欲しい文字コードは人によって異なる」と書いた通りで、「メモ帳などが出力するUTF-8(BOMなし)のテキストを判別」も個人差があるかと。ちなみに私は判断したいエンコーディングそれぞれを正規表現で表し、マッチするか判定しています。

    https://github.com/ffftp/ffftp/blob/v4.7/codecnv.cpp#L41-L89

    2020年6月22日 12:12
  • chardetの元ネタたる、nsCharsetDetector https://hg.mozilla.org/mozilla-central/file/bc7deafdac4b/extensions/universalchardet
    あたりから不要なcharset検出器を抜くのがいいかと思いますけどね。

    jzkey

    2020年6月23日 1:05
  • 佐祐理さん、jzkeyさん、実例を見せていただきありがとうございます。

    CStdioFile::ReadString()は便利な仕組みだったのですが、今となっては、
    ブラウザやメーラーやテキストエディタなどがやっている高度な文字コード判定を、
    単純なテキスト読み込みでも行わなければいけないのですね。
    2020年6月25日 2:25
  • > ブラウザやメーラーやテキストエディタなどがやっている高度な文字コード判定

    現実は結構、誤判定もあるようです。
    30MほどのCSVファイルを VSCodeに読み込ませたら、 ISO-8859-2 と判断され、見事文字化け(本来は S-JIS)。 Googleで、 "ISO8859-2"まで、打ち込んだら、候補に "ISO8859-2 vscode" が、あって大半が誤認識の話みたいです。(なんで、ISO8859-2 かは? ですが)

    別のエディタでもあって、一時、自動認識 Off にしてました。
    (ほとんど、英数字で、少しだけ日本語なんてのは難しそうな気がする)

    参考までに。

    2020年6月25日 11:56
  • pepperleaf01さん、ご意見ありがとうございます。
    Unicode以外の他国語が絡んでくると、この辺の判定が大変なのはよくわかります。

    この先、他国語に対応する必要はないものに対しても、
    UTF-8やUTF-16は想定しておかなければいけないのだろうとは思いますが、
    これまで前提だったShift-JISを捨てるわけにもいかないですし、
    自国語とUnicodeの自動判定くらいは欲しかったところです。
    2020年6月29日 0:19