一、概述
当前文章介绍如何在Linux(Ubuntu)下使用C语言调用libcurl库获取天气预报的方法。通过HTTP GET请求访问百度天气API,并解析返回的JSON数据,可以获取指定城市未来7天的天气预报信息。
二、设计思路
【1】使用libcurl库进行HTTP GET请求
- 在代码中包含
<curl/curl.h>
头文件,以便使用libcurl库 - 使用
curl_easy_init()
函数初始化curl - 设置请求选项,包括URL、写回调函数和写数据参数
- 使用
curl_easy_perform()
函数执行请求
【2】编写回调函数,将响应数据存储在内存中
- 定义一个结构体,包含存储响应数据的指针和长度
- 在回调函数中将响应数据拷贝到内存中,并动态调整内存大小
- 返回已拷贝的数据大小
【3】解析JSON数据
- 使用
json_tokener_parse()
函数解析返回的JSON数据 - 使用
json_object_object_get_ex()
函数获取指定字段的值 - 使用
json_object_array_length()
函数获取数组长度 - 使用
json_object_array_get_idx()
函数获取数组中的元素 - 使用
json_object_get_string()
函数获取字符串值
【4】打印天气预报信息
- 遍历获取到的天气预报数据,依次获取日期、天气和温度
- 使用
printf()
函数打印每一天的天气预报信息
三、关键代码
以下是主要的代码片段:
// 定义回调函数,用于将响应数据存储在内存中
size_t write_callback(void *ptr, size_t size, size_t nmemb, void *stream) {
// ...
}
// 子函数,用于获取指定城市未来7天的天气预报
int get_weather_forecast(const char *city) {
// ...
}
int main() {
const char *city = "your_city_code";
int ret = get_weather_forecast(city);
// ...
}
四、使用说明
【1】替换API密钥和城市代码:在示例代码中,将your_ak
和your_city_code
替换为你自己的百度API密钥和城市代码。
【2】编译代码:使用合适的C编译器,如gcc,编译代码。
gcc -o download_program download_program.c -lcurl
【3】运行代码:在终端中运行生成的可执行文件。
./download_program
【4】查看天气预报:程序会打印出指定城市未来7天的天气预报信息。
五、完整代码
HTTP GET请求访问百度天气API,并解析返回的JSON数据获取需要的天气信息。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <json-c/json.h>
// 定义回调函数,用于将响应数据存储在内存中
size_t write_callback(void *ptr, size_t size, size_t nmemb, void *stream) {
size_t realsize = size * nmemb;
struct string *mem = (struct string *)stream;
mem->ptr = realloc(mem->ptr, mem->len + realsize + 1);
if (mem->ptr == NULL) {
fprintf(stderr, "内存分配失败\n");
return 0;
}
memcpy(&(mem->ptr[mem->len]), ptr, realsize);
mem->len += realsize;
mem->ptr[mem->len] = '\0';
return realsize;
}
// 子函数,用于获取指定城市未来7天的天气预报
int get_weather_forecast(const char *city) {
char url[256];
sprintf(url, "https://api.map.baidu.com/weather/v1/?district_id=%s&ak=your_ak", city);
CURL *curl = curl_easy_init();
struct string response;
response.ptr = malloc(1);
response.len = 0;
if (curl && response.ptr) {
// 设置请求选项
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
// 执行请求
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
fprintf(stderr, "请求失败: %s\n", curl_easy_strerror(res));
free(response.ptr);
curl_easy_cleanup(curl);
return -1;
}
// 解析JSON数据
struct json_object *json = json_tokener_parse(response.ptr);
if (json == NULL) {
fprintf(stderr, "JSON解析失败\n");
free(response.ptr);
curl_easy_cleanup(curl);
return -1;
}
// 解析天气预报
struct json_object *result, *weather_data;
json_object_object_get_ex(json, "result", &result);
json_object_object_get_ex(result, "weather_data", &weather_data);
int i;
int num_days = json_object_array_length(weather_data);
for (i = 0; i < num_days; i++) {
struct json_object *day = json_object_array_get_idx(weather_data, i);
const char *date, *weather, *temperature;
date = json_object_get_string(json_object_object_get(day, "date"));
weather = json_object_get_string(json_object_object_get(day, "weather"));
temperature = json_object_get_string(json_object_object_get(day, "temperature"));
printf("日期:%s\n天气:%s\n温度:%s\n\n", date, weather, temperature);
}
free(response.ptr);
json_object_put(json);
} else {
fprintf(stderr, "初始化失败\n");
if (response.ptr) {
free(response.ptr);
}
if (curl) {
curl_easy_cleanup(curl);
}
return -1;
}
curl_easy_cleanup(curl);
return 0;
}
int main() {
const char *city = "your_city_code";
int ret = get_weather_forecast(city);
if (ret == 0) {
printf("天气预报获取成功!\n");
} else {
printf("天气预报获取失败!\n");
}
return 0;
}
在示例代码中,使用curl_easy_setopt
函数设置HTTP GET请求的URL,并通过CURLOPT_WRITEFUNCTION
和CURLOPT_WRITEDATA
选项指定回调函数,将响应数据存储在内存中。
然后,使用json_tokener_parse
函数解析返回的JSON数据,并提取其中的天气预报信息。通过json_object_object_get
和json_object_array_get_idx
等函数获取JSON对象和数组中的数据。
注意:代码中的URL中的YOUR_AK
和YOUR_CITY_CODE
需要使用你自己的百度API密钥和城市代码替换。
通过调用get_weather_forecast
函数,可以获取指定城市未来7天的天气预报并打印出来。