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

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

新規登録して質問してみよう
ただいま回答率
87.20%
VC++

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

cURL

cURLはHTTP, FTPやTelnetなど複数のプロトコルを用いてデータを転送するライブラリとコマンドラインツールを提供します。

解決済

HTTPレスポンス内に含まれる日本語がUnicode文字になる。

keroyu
keroyu

総合スコア1

VC++

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

cURL

cURLはHTTP, FTPやTelnetなど複数のプロトコルを用いてデータを転送するライブラリとコマンドラインツールを提供します。

1回答

0評価

0クリップ

194閲覧

投稿2022/05/05 15:44

前提と問題

curlを用いてMediaWikiのAPIを叩き、特定のページのwikitextを得るプログラムを、C++を用いて組んでいます。実行時、レスポンス自体は正しく返ってくる(ステータスコードが200)のですが、レスポンスに含まれる日本語がUnicode文字として返ってきてしまいます。

実現したいこと

  • レスポンスを、後述の期待する出力の項に示されるような形式で得たい。

該当のソースコード

以下Main()関数内。変数urlはUITF8でパーセントエンコーディングされたURL。

c++

CURL* curl = curl_easy_init(); Buffer* buf = new Buffer(); //ヘッダー curl_slist* headers = nullptr; headers = curl_slist_append(headers, "Content-Type : application/json; charset=utf-8"); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_WRITEDATA, buf); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback); curl_easy_setopt(curl, CURLOPT_HEADER, headers); curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "UTF-8"); curl_easy_perform(curl); long* response_code = (long*)malloc(sizeof(long)); //ステータスコード curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, response_code); char end = '\0'; buf->data = (char*)realloc(buf->data, buf->data_size + sizeof(char)); memcpy(buf->data + buf->data_size, &end, sizeof(char)); curl_easy_cleanup(curl); delete(buf);

以下Main()内で使用した自作関数と自作クラス

c++

struct Buffer { char* data = nullptr; int data_size = 0; }; //curlのコールバック size_t callback(void* buffer, size_t size, size_t nmemb, void* userp) { size_t realsize = size * nmemb; Buffer* buf = (Buffer*)userp; if (buf == nullptr) return realsize; if (!buf->data) { buf->data = (char*)malloc(realsize); } else { buf->data = (char*)realloc(buf->data, buf->data_size + realsize); } if (buf->data) { memcpy(buf->data + buf->data_size, buffer, realsize); buf->data_size += realsize; } return realsize; }

コード実行時の、curl_easy_cleanup(curl);でブレークした際のbuf->dataの内容

HTTP/1.1 200 OK Connection: keep-alive Content-Length: 2185 content-type: application/json; charset=utf-8 x-content-type-options: nosniff x-frame-options: DENY content-disposition: inline; filename=api-result.json cache-control: private, must-revalidate, max-age=0 x-envoy-upstream-service-time: 70 X-Datacenter: SJC Accept-Ranges: bytes X-Cacheable: NO:Cache-Control=private Date: Thu, 05 May 2022 15:09:07 GMT X-Served-By: cache-wk-sjc11421-SJC, cache-tyo11922-TYO X-Cache: MISS, MISS X-Cache-Hits: 0, 0 X-Timer: S1651763347.149674,VS0,VE177 Vary: Accept-Encoding, Treat-as-Untrusted, Cookie Set-Cookie: wikia_beacon_id=YH1Gq-ALwC; domain=.fandom.com; path=/; expires=Tue, 01 Nov 2022 15:09:07 GMT; SameSite=None; Secure; Set-Cookie: wikia_session_id=zjwddvu88d; domain=.fandom.com; path=/; expires=Thu, 05 May 2022 15:39:07 GMT; SameSite=None; Secure; Set-Cookie: _b2=ZYE7xfiRcH.1651763347150; domain=.fandom.com; path=/; expires=Sat, 04 May 2024 15:09:07 GMT; SameSite=None; Secure; Set-Cookie: Geo={%22region%22:%2208%22%2C%22city%22:%22tsukuba%22%2C%22country_name%22:%22japan%22%2C%22country%22:%22JP%22%2C%22continent%22:%22AS%22}; path=/; domain=.fandom.com; SameSite=None; Secure; {"parse":{"title":"SCP-165-JP \u30d8\u30a4\u30eb\u30b0\u30ed\u30fc\u30d6","pageid":6907,"wikitext":{"*":"{{Cardtable| card_type = \u30aa\u30d6\u30b8\u30a7\u30af\u30c8| sub_type = | type = Euclid| number = 165| name = SCP-165-JP \u30d8\u30a4\u30eb\u30b0\u30ed\u30fc\u30d6| image =420dfff8-eccc-4ee0-8092-50f2734d8d53.jpg| object_class =Euclid| attack =0| cost =2| effect_text =\u2460\u3053\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306f\u8ca1\u56e3\u4e0a\u3092\u96e2\u308c\u306a\u3044\u3002<br> \u2461\u81ea\u5206\u306e\u30bf\u30fc\u30f3\u958b\u59cb\u6642\u306b\u767a\u52d5\u3059\u308b\u3002\u81ea\u5206\u307e\u305f\u306f\u76f8\u624b\u4eba\u4e8b\u3092\u3053\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u4e0b\u306b\u91cd\u306d\u308b\u3002<br> \u2462\u2461\u306e\u52b9\u679c\u3092\u767a\u52d5\u3057\u3066\u304b\u30895\u30bf\u30fc\u30f3\u5f8c\u306e\u30bf\u30fc\u30f3\u7d42\u4e86\u6642\u306b\u767a\u52d5\u3059\u308b\u3002\u3053\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u4e0b\u306b\u5b58\u5728\u3059\u308b\u4eba\u4e8b\u3092decommissioned\u306b\u9001\u308b\u3002<br>| flavor_text = \u5c0f\u585a\u7814\u7a76\u54e1: \u8336\u8272\u3058\u3083\u3054\u4e0d\u6e80\u304b\u3002<br><br>SCP-165-JP-A: \u52ff\u8ad6\uff01 \u3082\u3046\u5c11\u3057\u660e\u308b\u3044\u8272\u306e\u65b9\u304c\u3044\u3044\u306d\u3002<br> \u305d\u308c\u3068\u3053\u306e\u5b89\u3063\u307d\u3055\u304c\u6c17\u306b\u5165\u3089\u306a\u3044\u30022000\u5186\u3082\u3057\u306a\u3044\u306a\u3053\u308c\u306f\u3002<br>| tags =scp-jp \u4eba\u9593\u578b \u5bb9\u5668 \u77ac\u9593\u79fb\u52d5 \u7cbe\u795e\u5f71\u97ff| limited = | effect_tags = |source =<span class=\"ui_wikidb_title\">\u51fa\u5178</span>&nbsp;JP<br><span class=\"ui_bottom_detail\">\"kasyu-maki\"\u4f5c SCP-165-JP - \u30d8\u30a4\u30eb\u30b0\u30ed\u30fc\u30d6<br>\"https://scptcgjpjwiki.gamerch.com/gamerch/external_link/?url=http%3A%2F%2Fja.scp-wiki.net%2Fscp-165-jp\" http://ja.scp-wiki.net/scp-165-jp<br><br>\u30ab\u30fc\u30c9\u516c\u958b\u5148<br>\"https://scptcgjpjwiki.gamerch.com/gamerch/external_link/?url=https%3A%2F%2Ftwitter.com%2Fkeroyu_scp%2Fstatus%2F1283263861898932224\" https://twitter.com/keroyu_scp/status/1283263861898932224<br></span>}}"}}}

期待する出力

HTTP/1.1 200 OK Connection: keep-alive Content-Length: 2185 content-type: application/json; charset=utf-8 x-content-type-options: nosniff x-frame-options: DENY content-disposition: inline; filename=api-result.json cache-control: private, must-revalidate, max-age=0 x-envoy-upstream-service-time: 70 X-Datacenter: SJC Accept-Ranges: bytes X-Cacheable: NO:Cache-Control=private Date: Thu, 05 May 2022 15:09:07 GMT X-Served-By: cache-wk-sjc11421-SJC, cache-tyo11922-TYO X-Cache: MISS, MISS X-Cache-Hits: 0, 0 X-Timer: S1651763347.149674,VS0,VE177 Vary: Accept-Encoding, Treat-as-Untrusted, Cookie Set-Cookie: wikia_beacon_id=YH1Gq-ALwC; domain=.fandom.com; path=/; expires=Tue, 01 Nov 2022 15:09:07 GMT; SameSite=None; Secure; Set-Cookie: wikia_session_id=zjwddvu88d; domain=.fandom.com; path=/; expires=Thu, 05 May 2022 15:39:07 GMT; SameSite=None; Secure; Set-Cookie: _b2=ZYE7xfiRcH.1651763347150; domain=.fandom.com; path=/; expires=Sat, 04 May 2024 15:09:07 GMT; SameSite=None; Secure; Set-Cookie: Geo={%22region%22:%2208%22%2C%22city%22:%22tsukuba%22%2C%22country_name%22:%22japan%22%2C%22country%22:%22JP%22%2C%22continent%22:%22AS%22}; path=/; domain=.fandom.com; SameSite=None; Secure; {"parse":{"title":"SCP-165-JP ヘイルグローブ","pageid":6907,"wikitext":{"*":"{{Cardtable| card_type = オブジェクト| sub_type = | type = Euclid| number = 165| name = SCP-165-JP ヘイルグローブ| image =420dfff8-eccc-4ee0-8092-50f2734d8d53.jpg| object_class =Euclid| attack =0| cost =2| effect_text =①このオブジェクトは財団上を離れない。<br> ②自分のターン開始時に発動する。自分または相手人事をこのオブジェクトの下に重ねる。<br> ③②の効果を発動してから5ターン後のターン終了時に発動する。このオブジェクトの下に存在する人事をdecommissionedに送る。<br>| flavor_text = 小塚研究員: 茶色じゃご不満か。<br><br>SCP-165-JP-A: 勿論! もう少し明るい色の方がいいね。<br> それとこの安っぽさが気に入らない。2000円もしないなこれは。<br>| tags =scp-jp 人間型 容器 瞬間移動 精神影響| limited = | effect_tags = |source =<span class="ui_wikidb_title">出典</span>&nbsp;JP<br><span class="ui_bottom_detail">"kasyu-maki"作 SCP-165-JP - ヘイルグローブ<br>"https://scptcgjpjwiki.gamerch.com/gamerch/external_link/?url=http%3A%2F%2Fja.scp-wiki.net%2Fscp-165-jp" http://ja.scp-wiki.net/scp-165-jp<br><br>カード公開先<br>"https://scptcgjpjwiki.gamerch.com/gamerch/external_link/?url=https%3A%2F%2Ftwitter.com%2Fkeroyu_scp%2Fstatus%2F1283263861898932224" https://twitter.com/keroyu_scp/status/1283263861898932224<br></span>}}"}}}

試したこと

curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "UTF-8");を追加したり、リクエストヘッダにcharset=utf-8を追加したりしましたが、出力に変化はありませんでした。

補足情報

OSはWindows10。
Visual Studio 2022でC++20を使用。
vcpkgを用いてcurlのver7.82.0をインストール、使用。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

hoshi-takanori

2022/05/05 16:17

「Unicode文字」って何だろう? と思ったら、Unicode エスケープされた文字ってことですね。それも正しい JSON であり、適切に JSON をパースすれば普通の文字列になるはず…。

まだ回答がついていません

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

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

VC++

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

cURL

cURLはHTTP, FTPやTelnetなど複数のプロトコルを用いてデータを転送するライブラリとコマンドラインツールを提供します。