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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

VC++

VC++ (Visual C++) とは、Microsoft製のC++のための統合開発環境です。

MFC

MFC (Microsoft Fouondation Class)とは、MicrosoftがVC++用に開発したWindows用アプリケーションのフレームワークです。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

UTF-8

UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。

Q&A

2回答

999閲覧

Win10 VS2015 VC++ MFC (Unicode)で漢字入りJSONを正しく読み書きできるライブラリは実在するか。(続)

Kazumori102

総合スコア45

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

VC++

VC++ (Visual C++) とは、Microsoft製のC++のための統合開発環境です。

MFC

MFC (Microsoft Fouondation Class)とは、MicrosoftがVC++用に開発したWindows用アプリケーションのフレームワークです。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

UTF-8

UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。

0グッド

0クリップ

投稿2022/09/04 09:02

前提

まず、経験の浅い物のため、ものをあまり知らないことを許していただきたい。

表題の環境下でJSONライブラリで漢字入りJSONを読み込もうとし、下記のライブラリを試したが、エスケープキャラクターでエラーが出る。
JSONはUTF-8でエンコードされているからダメ文字等はないはずだが、この問題が起きる。

  • PicoJSON
  • RapidJSON
  • nlohmnn-jsonn
  • Json11

規格上漢字をはじめとする日本語は要エンコードではないということも確認した。
デバッグしていくと、ファイルの読み込みはともかく、ライブラリにデータを渡した後にエラーが起きているように見える。
ただし、Win環境はエンコード周りが怪しい…。
なお、RapidJSONはダメ文字をバックスラッシュで回避することで読み込めたが、本来不要な処理なはずである。
Linux上では正常に動いている様子はよく見かけるが…。

※前回のが埋もれてしまったのか進展がないので再投稿。
解答いただけたら古いのも終了とします。

実現したいこと

漢字入りJSONを正しく読み込めるライブラリ、もしくは上記の試したライブラリの正しい扱い方を知る。

下記はBOM無しUTF-8でエンコードし保存 (補足要求を念のためこちらでも回答)

kanji_included.json

1{ 2 "bad_string" : "表現" 3}

発生している問題・エラーメッセージ

エスケープシーケンスが含まれる等のメッセージ

該当のソースコード

現在使用しているコード

C++

1FILE* fileR; //読込用ファイルポインタ 2CString bufReadJSON; //読込バッファ 3CString csResultReadJSON = NULL; //読込結果 4 5CStdioFile cFileR(fileR); //読込用ファイルポインタの変形したもの 6 7while (cFileR.ReadString(bufReadJSON)) { 8 csResultReadJSON += bufReadJSON + _T("\n"); 9} 10 11CStringA csaResultReadJSON(csResultReadJSON.GetBuffer(0)); 12std::string ssResultReadJSON = csaResultReadJSON.GetBuffer(0); 13csResultReadJSON.ReleaseBuffer(0); 14csaResultReadJSON.ReleaseBuffer(0); 15 16rapidjson::Document hoge 17 18hoge.Parse(ssResultReadJSON.c_str()); 19ssResultReadJSON.clear();

→パースされずにエスケープシーケンスエラー

std::stringの内部表現をShiftJISからUTF-8に変えるらしいコードを試した

C++

1std::string ssu8ResultReadJSON = ""; 2 3std::ifstream ifs; 4ifs.open(PARAMSAVE, std::ios::binary); 5 6std::string ssBufReadJSON; 7while (getline(ifs, ssBufReadJSON)) { 8 ssu8ResultReadJSON += ssBufReadJSON; 9} 10 11int lenUni = MultiByteToWideChar(CP_UTF8, 0, ssu8ResultReadJSON.c_str(), ssu8ResultReadJSON.size() + 1, NULL, 0); 12 13wchar_t* bufUni = new wchar_t[lenUni]; 14 15MultiByteToWideChar(CP_UTF8, 0, ssu8ResultReadJSON.c_str(), ssu8ResultReadJSON.size() + 1, bufUni, lenUni); 16 17int lenSJ = WideCharToMultiByte(CP_THREAD_ACP, 0, bufUni, -1, NULL, 0, NULL, NULL); 18 19char* cpResultReadJSON = new char[lenSJ]; 20 21WideCharToMultiByte(CP_THREAD_ACP, 0, bufUni, lenUni + 1, cpResultReadJSON, lenSJ, NULL, NULL); 22 23rapidjson::Document hoge 24hoge.Parse(cpResultReadJSON);

→ダメだった。(詳細失念)
文字化けかエスケープシーケンスエラーのどちらかの発生。

Json11を使ってみた

C++

1FILE* fileR = NULL; //読込用ファイルポインタ 2CStdioFile cFileR; 3CString bufReadJSON; //読込バッファ 4CString csResultReadJSON = NULL; //読込結果 5 6_tfopen_s(&fileR, PARAMSAVE, _T("r,ccs=UTF-8")); 7 8 9CStdioFile cFileR(fileR); //読込用ファイルポインタの変形したもの 10 11while (cFileR.ReadString(bufReadJSON)) { 12 csResultReadJSON += bufReadJSON + _T("\n"); 13} 14 15CStringA csaResultReadJSON(csResultReadJSON.GetBuffer(0)); 16std::string ssResultReadJSON = csaResultReadJSON.GetBuffer(0); 17csResultReadJSON.ReleaseBuffer(0); 18csaResultReadJSON.ReleaseBuffer(0); 19std::string ssErr; 20jsonDoc.ParseString(ssResultReadJSON, ssErr);

→パースされずにエスケープシーケンスエラー

Json11使ってみた(2:std::stringに統一)

C++

1std::string ssResultReadJSON = ""; 2 3std::ifstream ifs; 4ifs.open(PARAMSAVE, std::ios::binary); 5 6std::string ssBufReadJSON; 7while (getline(ifs, ssBufReadJSON)) { 8 ssResultReadJSON += ssBufReadJSON; 9} 10 11std::string ssErr; 12auto jsonDoc = json11::Json::parse(ssResultReadJSON, ssErr);

→パースはされるが出力すると文字化けている。

試したこと

ファイルの読み出し方を変えたり、CStringに入れたりStd::Stringに入れたり、変換方法を変えてみたりした。

補足情報(FW/ツールのバージョンなど)

さらに詳細な情報の希望があれば可能な限り開示。

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

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

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

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

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

y_waiwai

2022/09/04 10:15

エラーが出たなら、エラーメッセージを提示しましょう エラーメッセージは、よけいな省略翻訳しないで出たそのママをコピペで提示してください
guest

回答2

0

Json11使ってみた(2:std::stringに統一)版でやってみたけど、ここでのstringの中身はutf8なので、それを使うタイミングでutf16変換してCStringWとかstd::wstringとかで返せばいいのでは。
ぱっと見json11.cppはutf8前提のコードに見えるので。

c++

1CStringW ConvertFromUTF8(const std::string& utf8) 2{ 3 if (utf8.empty()) return L""; 4 CStringW uni; 5 const int cc = MultiByteToWideChar(CP_UTF8, 0, utf8.data(), utf8.size(), NULL, 0); 6 if (cc > 0) 7 { 8 wchar_t* buf = uni.GetBuffer(cc); 9 MultiByteToWideChar(CP_UTF8, 0, utf8.data(), utf8.size(), buf, cc); 10 uni.ReleaseBuffer(cc); 11 } 12 return uni; 13} 14 15{ 16auto jsonDoc = json11::Json::parse(ssResultReadJSON, ssErr); 17CStringW val = ConvertFromUTF8(jsonDoc["bad_string"].string_value()); 18}

投稿2022/09/04 09:52

matukeso

総合スコア1590

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

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

0

漢字入りJSONを正しく読み書きできるライブラリは実在するか。

単にあなたの使い方がまずいだけなんでは

投稿2022/09/04 10:30

y_waiwai

総合スコア87774

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

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

Kazumori102

2022/09/04 11:00

その通りです。 が、例を探しても上にあげたもの以上のは探し方が悪いのか見当たらないのです。
y_waiwai

2022/09/04 11:07

使い方がまずいと思うなら、それを聞けばいいのでは。 いきなり実在するのかと聞かれても答えようがない。 前の質門で放置されたのはそういうことでしょ
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問