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

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

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

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

C++

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

Q&A

解決済

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

Japaneasee
Japaneasee

総合スコア6

cURL

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

C++

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

1回答

0グッド

0クリップ

286閲覧

投稿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

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

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

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

下記のような質問は推奨されていません。

  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

dameo

2023/01/27 22:57 編集

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

回答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

総合スコア5027

下記のような回答は推奨されていません。

  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

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

ただいまの回答率
86.02%

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

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

質問する

関連した質問

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

cURL

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

C++

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