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

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

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

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

1009閲覧

C++のlibcurlでGETリクエストをすると文字化けする

Japaneasee

総合スコア6

cURL

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2023/01/27 20:45

libcurlでGETメソッドを使い、日本語が含まれているサイトにリクエストをすると日本語が文字化けしてしまいます。

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

あまりにも長文になってしまうので、文字化けしている部分の切り抜きです。

<meta property="og:title" content="繧ィ繝ウ繧ク繝九い縺ォ髢「縺吶k遏・隴倥r險倬鹸繝サ蜈ア譛峨☆繧九◆繧√・繧オ繝シ繝薙せ - Qiita">

該当のソースコード

C++

1#include <stdio.h> 2#include <iostream> 3#include <string> 4#include <curl/curl.h> 5 6#include <fstream> 7 8using namespace std; 9 10 11size_t write_data(void* ptr, size_t size, size_t nmemb, string* data) { 12 data->append((char*)ptr, size * nmemb); 13 return size * nmemb; 14} 15 16int main() { 17 CURL* curl; 18 CURLcode res; 19 20 string buffer; 21 22 curl_slist* headers = NULL; 23 24 curl = curl_easy_init(); 25 26 if (curl) { 27 curl_easy_setopt(curl, CURLOPT_URL, "https://qiita.com/"); 28 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); 29 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer); 30 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); 31 headers = curl_slist_append(headers, "Accept-Charset: utf-8"); 32 curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "utf-8"); 33 res = curl_easy_perform(curl); 34 curl_easy_cleanup(curl); 35 36 } 37 38 cout << buffer << endl; 39 40 return 0; 41}

試したこと

この部分の追加

C++

1headers = curl_slist_append(headers, "Accept-Charset: utf-8"); 2curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "utf-8");

補足情報(バージョンなど)

OS: Windows 10
Visual Studio 2022
C++98

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

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

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

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

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

dameo

2023/01/27 22:57 編集

文字化けの意味が明確じゃありません。Linuxで試したところ、正しくutf-8が返っています。 (追記) 伝わってないかもしれませんね。例えば、コマンドプロンプト上でデフォルトの設定(cp932)のままutf-8を標準出力に垂れ流せば文字化けしますが、それはlibcurlと何の関係もない端末及びその設定の問題です。
guest

回答1

0

ベストアンサー

おそらく curl での取得自体は成功しています。

Windows のコンソールは設定されているコードページに従って文字コードを解釈します。 日本語で Windows を使っているなら普通は 932 に設定されていて、これはいわゆる Shift_JIS です。 一般的にウェブサイトは UTF-8 で書かれており、それをコンソールが Shift_JIS のつもりで解釈して表示するので結果的に化けた状態になります。

符号の性質上、繧や繝は UTF-8 を Shift_JIS として解釈したときに頻出する文字なのでわかりやすいです。

これを解決するにはいくつか方法がありますが歴史的事情によって一長一短があります。

Shift_JIS に変換する

Shift_JIS として解釈されるので Shift_JIS に変換して出力するというのは最も単純な考え方です。

ただし、コンソールの側の設定が異なるときは化けてしまいます。 また、 Unicode に有って Shift_JIS に無い文字というものもたくさんあるのでそのような文字が含まれる場合にはまともに表示できません。

コンソール側の設定を変える

chcp 65001 コマンドでコンソールのコードページを UTF-8 に切り替えることが出来ます。 UTF-8 で出力したものが UTF-8 で解釈されるようになるので意図したとおり表示されるでしょう。

自分以外が使うプログラムでユーザに対して設定を切り替えてもらわないといけないというのはちょっと困るかもしれません。

コンソールAPIを使う

標準出力の実体はプロセス間通信の一種ですが、標準出力を経由せずにコンソールの読み書きをする API (いわゆるコンソール API)も用意されており、これを使えばコンソールの設定に左右されずに表示することが出来ます。

ただし API は UTF-16 を使うことになっているので元が UTF-8 なら変換は必要です。 また、コードページの設定には左右されませんがフォント設定の影響は受けるので設定されているフォント内に表示しようとする文字のグリフが格納されていなければ思ったように表示されないかもしれません。

また、コンソール API は直接的にコンソールに書き込むのでリダイレクトは出来なくなります。

投稿2023/01/29 03:07

SaitoAtsushi

総合スコア5444

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問