#include <iconv.h>
#include <curl/curl.h>
#include <nlohmann/json.hpp>
#define GLOG_NO_ABBREVIATED_SEVERITIES
#include <glog/logging.h>
using namespace std;
int char_code_convert(
const string& from, const string& to,
const string& in, string& out)
{
const iconv_t cd = iconv_open(to.c_str(),
from.c_str());
if (cd == nullptr)
{
return -1;
}
out.resize(in.size() * 2, 0);
char* pin = const_cast<char*>(in.data());
size_t in_len = in.size();
char* pout = const_cast<char*>(out.data());
size_t out_len = out.size();
if (iconv(cd, &pin, &in_len, &pout, &out_len) == -1)
{
return -1;
}
iconv_close(cd);
return 0;
}
int writer(char* data, const size_t size, const size_t nmemb, string* writerData)
{
const unsigned long sizes = size * nmemb;
if (writerData == nullptr)
return -1;
writerData->append(data, sizes);
return sizes;
}
int GetData(string& ip, string& city)
{
string buffer;
try
{
curl_global_init(CURL_GLOBAL_ALL);
const string url_str = "http://pv.sohu.com/cityjson?ie=utf-8";
CURL* p_curl = curl_easy_init();
if (nullptr != p_curl)
{
curl_easy_setopt(p_curl, CURLOPT_TIMEOUT, 10);
curl_easy_setopt(p_curl, CURLOPT_URL, url_str.c_str());
curl_easy_setopt(p_curl, CURLOPT_WRITEFUNCTION, writer);
curl_easy_setopt(p_curl, CURLOPT_WRITEDATA, &buffer);
const CURLcode res = curl_easy_perform(p_curl);
LOG_IF(ERROR, res != CURLE_OK) << "curl_easy_perform() failed " << curl_easy_strerror(res);
curl_easy_cleanup(p_curl);
}
curl_global_cleanup();
}
catch (std::exception& ex)
{
LOG(ERROR) << "curl exception=" << ex.what();
return -1;
}
if (buffer.empty())
{
LOG(ERROR) << "!!! ERROR The sever response NULL";
return -1;
}
try
{
const auto it1 = buffer.find('{');
const auto it2 = buffer.find('}') + 1;
const auto json_content = buffer.substr(it1, it2 - it1);
nlohmann::json obj = nlohmann::json::parse(json_content);
ip = obj["cip"].get<string>();
city = obj["cname"].get<string>();
}
catch (std::exception& e)
{
LOG(ERROR) << "PARSE ERROR. exception=" << e.what();
return -1;
}
return 0;
}
int main(int argc, char const* argv[])
{
string ip, city, chn_city;
const int ret = GetData(ip, city);
char_code_convert("UTF-8", "GB2312", city, chn_city);
LOG_IF(ERROR, ret != 0) << "get data error";
LOG(INFO) << "ip=" << ip << " city=" << chn_city;
return 0;
}